From 9947f5bcc0c1eefa6ebfaaa6e3604544dda3e900 Mon Sep 17 00:00:00 2001 From: Mohamad Chaarawi Date: Wed, 20 Mar 2013 13:25:49 -0500 Subject: [svn-r23404] switching to use new async API --- MANIFEST | 3 + src/H5FF.c | 837 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/H5FFprivate.h | 49 +++ src/H5FFpublic.h | 91 ++++++ src/H5Pdxpl.c | 4 +- src/H5Pint.c | 50 ++- src/H5Pprivate.h | 5 + src/H5VLiod.c | 747 +++++++++++++++++++++++++++++++++----------- src/H5VLiod_client.c | 134 +++++--- src/H5VLiod_client.h | 13 +- src/H5VLiod_server.c | 53 ++-- src/Makefile.am | 1 + src/Makefile.in | 4 +- src/hdf5.h | 1 + testpar/test_client.c | 64 +++- 15 files changed, 1781 insertions(+), 275 deletions(-) create mode 100644 src/H5FF.c create mode 100644 src/H5FFprivate.h create mode 100644 src/H5FFpublic.h diff --git a/MANIFEST b/MANIFEST index 888e3a4..930809c 100644 --- a/MANIFEST +++ b/MANIFEST @@ -697,6 +697,9 @@ ./src/H5FDstdio.h ./src/H5FDwindows.c ./src/H5FDwindows.h +./src/H5FF.c +./src/H5FFprivate.h +./src/H5FFpublic.h ./src/H5FL.c ./src/H5FLprivate.h ./src/H5FO.c diff --git a/src/H5FF.c b/src/H5FF.c new file mode 100644 index 0000000..ea9aa09 --- /dev/null +++ b/src/H5FF.c @@ -0,0 +1,837 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the files COPYING and Copyright.html. COPYING can be found at the root * + * of the source code distribution tree; Copyright.html can be found at the * + * root level of an installed copy of the electronic HDF5 document set and * + * is linked from the top-level documents page. It can also be found at * + * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * + * access to either file, you may request a copy from help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * Programmer: Quincey Koziol + * March, 2013 + * + * Purpose: Wrappers around existing HDF5 to support Exascale FastForward + * functionality. + * + */ + + +/****************/ +/* Module Setup */ +/****************/ + + +/***********/ +/* Headers */ +/***********/ +#include "H5private.h" /* Generic Functions */ +#include "H5Eprivate.h" /* Error handling */ +#include "H5FFprivate.h" /* FastForward wrappers */ +#include "H5Iprivate.h" /* IDs */ +#include "H5MMprivate.h" /* Memory management */ +#include "H5Pprivate.h" /* Property lists */ +#include "H5VLiod.h" /* IOD plugin - tmp */ +#include "H5VLiod_client.h" /* Client IOD - tmp */ + + +/****************/ +/* Local Macros */ +/****************/ + + +/******************/ +/* Local Typedefs */ +/******************/ + + +/********************/ +/* Local Prototypes */ +/********************/ + + +/*********************/ +/* Package Variables */ +/*********************/ + + +/*****************************/ +/* Library Private Variables */ +/*****************************/ + + +/*******************/ +/* Local Variables */ +/*******************/ + + + +/*------------------------------------------------------------------------- + * Function: H5FF_set_async_flag + * + * Purpose: Helper routine to set up asynchronous I/O properties + * + * Return: Success: 0 + * Failure: <0 + * + * Programmer: Quincey Koziol + * Wednesday, March 20, 2013 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5FF_set_async_flag(H5P_genplist_t *plist, const H5_request_t *req) +{ + hbool_t do_async; /* Whether we're going to do async. I/O */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Sanity check */ + HDassert(plist); + HDassert(req); + + /* Check if we are performing asynchronous I/O */ + do_async = req ? TRUE : FALSE; + + /* Set the async. I/O operation flag */ + if(H5P_set(plist, H5P_ASYNC_FLAG_NAME, &do_async) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "can't set async flag") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5FF_set_async_flag() */ + + +/*------------------------------------------------------------------------- + * Function: H5FF_get_async_req + * + * Purpose: Helper routine to get asynchronous I/O request + * + * Return: Success: 0 + * Failure: <0 + * + * Programmer: Quincey Koziol + * Wednesday, March 20, 2013 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5FF_get_async_req(H5P_genplist_t *plist, H5_request_t *req) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Sanity check */ + HDassert(plist); + HDassert(req); + + /* Retrieve the async. I/O operation request */ + if(H5P_get(plist, H5P_ASYNC_REQ_NAME, req) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get async request") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5FF_get_async_req() */ + + +/*------------------------------------------------------------------------- + * Function: H5FF_reset_async_flag + * + * Purpose: Helper routine to reset asynchronous I/O properties + * + * Return: Success: 0 + * Failure: <0 + * + * Programmer: Quincey Koziol + * Wednesday, March 20, 2013 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5FF_reset_async_flag(H5P_genplist_t *plist) +{ + hbool_t do_async = H5P_ASYNC_FLAG_DEF; /* Default async I/O flag */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Reset the async. I/O operation flag */ + if(H5P_set(plist, H5P_ASYNC_FLAG_NAME, &do_async) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "can't set async flag") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5FF_reset_async_flag() */ + + +/*------------------------------------------------------------------------- + * Function: H5Fcreate_ff + * + * Purpose: Asynchronous wrapper around H5Fcreate(). + * + * Return: Success: The placeholder ID for a new file. When + * the asynchronous operation completes, this + * ID will transparently be modified to be a + * "normal" ID. + * Failure: FAIL + * + * Programmer: Quincey Koziol + * Wednesday, March 20, 2013 + * + *------------------------------------------------------------------------- + */ +hid_t +H5Fcreate_ff(const char *filename, unsigned flags, hid_t fcpl_id, hid_t fapl_id, + H5_request_t *req) +{ + H5P_genplist_t *plist; /* Property list pointer */ + hbool_t pl_copied = FALSE; /* Whether the property list was copied */ + hbool_t pl_modified = FALSE; /* Whether the property list was modified */ + hid_t ret_value; /* Return value */ + + FUNC_ENTER_API(FAIL) + + /* Get property list */ + if(H5P_DEFAULT == fapl_id) { + if((fapl_id = H5Pcopy(H5P_FILE_ACCESS_DEFAULT)) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTCOPY, FAIL, "can't copy default property list") + pl_copied = TRUE; + } /* end if */ + else + if(TRUE != H5P_isa_class(fapl_id, H5P_FILE_ACCESS)) + HGOTO_ERROR(H5E_FILE, H5E_BADTYPE, FAIL, "wrong type of property list") + + /* Get the plist structure */ + if(NULL == (plist = (H5P_genplist_t *)H5I_object(fapl_id))) + HGOTO_ERROR(H5E_FILE, H5E_BADATOM, FAIL, "can't find object for ID") + + /* Set up the properties for an asynchronous operation */ + if(H5FF_set_async_flag(plist, req) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "can't set async request") + pl_modified = TRUE; + + + /* Perform the wrapped operation, possibly asynchronously */ + if((ret_value = H5Fcreate(filename, flags, fcpl_id, fapl_id)) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTCREATE, FAIL, "unable to perform wrapped operation") + + + /* Retrieve async request from property, if non-NULL */ + if(req) + if(H5FF_get_async_req(plist, req) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get async request") + +done: + if(pl_copied) { + if(H5Pclose(fapl_id) < 0) + HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEOBJ, FAIL, "unable to close copied property list") + } /* end if */ + else if(pl_modified) { + /* Clear the async info from property list, if not copied */ + if(H5FF_reset_async_flag(plist) < 0) + HDONE_ERROR(H5E_FILE, H5E_CANTRESET, FAIL, "unable to reset modified property list") + } /* end if */ + + FUNC_LEAVE_API(ret_value) +} /* end H5Fcreate_ff() */ + + +/*------------------------------------------------------------------------- + * Function: H5Fopen_ff + * + * Purpose: Asynchronous wrapper around H5Fopen(). + * + * Return: Success: The placeholder ID for a new file. When + * the asynchronous operation completes, this + * ID will transparently be modified to be a + * "normal" ID. + * Failure: FAIL + * + * Programmer: Quincey Koziol + * Wednesday, March 20, 2013 + * + *------------------------------------------------------------------------- + */ +hid_t +H5Fopen_ff(const char *filename, unsigned flags, hid_t fapl_id, + H5_request_t *req) +{ + H5P_genplist_t *plist; /* Property list pointer */ + hbool_t pl_copied = FALSE; /* Whether the property list was copied */ + hbool_t pl_modified = FALSE; /* Whether the property list was modified */ + hid_t ret_value; /* Return value */ + + FUNC_ENTER_API(FAIL) + + /* Get property list */ + if(H5P_DEFAULT == fapl_id) { + if((fapl_id = H5Pcopy(H5P_FILE_ACCESS_DEFAULT)) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTCOPY, FAIL, "can't copy default property list") + pl_copied = TRUE; + } /* end if */ + else + if(TRUE != H5P_isa_class(fapl_id, H5P_FILE_ACCESS)) + HGOTO_ERROR(H5E_FILE, H5E_BADTYPE, FAIL, "wrong type of property list") + + /* Get the plist structure */ + if(NULL == (plist = (H5P_genplist_t *)H5I_object(fapl_id))) + HGOTO_ERROR(H5E_FILE, H5E_BADATOM, FAIL, "can't find object for ID") + + /* Set up the properties for an asynchronous operation */ + if(H5FF_set_async_flag(plist, req) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "can't set async request") + pl_modified = TRUE; + + + /* Perform the wrapped operation, possibly asynchronously */ + if((ret_value = H5Fopen(filename, flags, fapl_id)) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENOBJ, FAIL, "unable to perform wrapped operation") + + + /* Retrieve async request from property, if non-NULL */ + if(req) + if(H5FF_get_async_req(plist, req) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get async request") + +done: + if(pl_copied) { + if(H5Pclose(fapl_id) < 0) + HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEOBJ, FAIL, "unable to close copied property list") + } /* end if */ + else if(pl_modified) { + /* Clear the async info from property list, if not copied */ + if(H5FF_reset_async_flag(plist) < 0) + HDONE_ERROR(H5E_FILE, H5E_CANTRESET, FAIL, "unable to reset modified property list") + } /* end if */ + + FUNC_LEAVE_API(ret_value) +} /* end H5Fopen_ff() */ + + +/*------------------------------------------------------------------------- + * Function: H5Gcreate_ff + * + * Purpose: Asynchronous wrapper around H5Gcreate(). + * + * Return: Success: The placeholder ID for a group. When + * the asynchronous operation completes, this + * ID will transparently be modified to be a + * "normal" ID. + * Failure: FAIL + * + * Programmer: Quincey Koziol + * Wednesday, March 20, 2013 + * + *------------------------------------------------------------------------- + */ +hid_t +H5Gcreate_ff(hid_t loc_id, const char *name, hid_t lcpl_id, + hid_t gcpl_id, hid_t gapl_id, + uint64_t /* UNUSED */ trans, H5_request_t *req) +{ + H5P_genplist_t *plist; /* Property list pointer */ + hbool_t pl_copied = FALSE; /* Whether the property list was copied */ + hbool_t pl_modified = FALSE; /* Whether the property list was modified */ + hid_t ret_value; /* Return value */ + + FUNC_ENTER_API(FAIL) + + /* Get property list */ + if(H5P_DEFAULT == gapl_id) { + if((gapl_id = H5Pcopy(H5P_GROUP_ACCESS_DEFAULT)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTCOPY, FAIL, "can't copy default property list") + pl_copied = TRUE; + } /* end if */ + else + if(TRUE != H5P_isa_class(gapl_id, H5P_GROUP_ACCESS)) + HGOTO_ERROR(H5E_SYM, H5E_BADTYPE, FAIL, "wrong type of property list") + + /* Get the plist structure */ + if(NULL == (plist = (H5P_genplist_t *)H5I_object(gapl_id))) + HGOTO_ERROR(H5E_SYM, H5E_BADATOM, FAIL, "can't find object for ID") + + /* Set up the properties for an asynchronous operation */ + if(H5FF_set_async_flag(plist, req) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTSET, FAIL, "can't set async request") + pl_modified = TRUE; + + + /* Perform the wrapped operation, possibly asynchronously */ + if((ret_value = H5Gcreate2(loc_id, name, lcpl_id, gcpl_id, gapl_id)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTCREATE, FAIL, "unable to perform wrapped operation") + + + /* Retrieve async request from property, if non-NULL */ + if(req) + if(H5FF_get_async_req(plist, req) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't get async request") + +done: + if(pl_copied) { + if(H5Pclose(gapl_id) < 0) + HDONE_ERROR(H5E_SYM, H5E_CANTCLOSEOBJ, FAIL, "unable to close copied property list") + } /* end if */ + else if(pl_modified) { + /* Clear the async info from property list, if not copied */ + if(H5FF_reset_async_flag(plist) < 0) + HDONE_ERROR(H5E_SYM, H5E_CANTRESET, FAIL, "unable to reset modified property list") + } /* end if */ + + FUNC_LEAVE_API(ret_value) +} /* end H5Gcreate_ff() */ + + +/*------------------------------------------------------------------------- + * Function: H5Gopen_ff + * + * Purpose: Asynchronous wrapper around H5Gopen(). + * + * Return: Success: The placeholder ID for a group. When + * the asynchronous operation completes, this + * ID will transparently be modified to be a + * "normal" ID. + * Failure: FAIL + * + * Programmer: Quincey Koziol + * Wednesday, March 20, 2013 + * + *------------------------------------------------------------------------- + */ +hid_t +H5Gopen_ff(hid_t loc_id, const char *name, hid_t gapl_id, + uint64_t /* UNUSED */ trans, H5_request_t *req) +{ + H5P_genplist_t *plist; /* Property list pointer */ + hbool_t pl_copied = FALSE; /* Whether the property list was copied */ + hbool_t pl_modified = FALSE; /* Whether the property list was modified */ + hid_t ret_value; /* Return value */ + + FUNC_ENTER_API(FAIL) + + /* Get property list */ + if(H5P_DEFAULT == gapl_id) { + if((gapl_id = H5Pcopy(H5P_GROUP_ACCESS_DEFAULT)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTCOPY, FAIL, "can't copy default property list") + pl_copied = TRUE; + } /* end if */ + else + if(TRUE != H5P_isa_class(gapl_id, H5P_GROUP_ACCESS)) + HGOTO_ERROR(H5E_SYM, H5E_BADTYPE, FAIL, "wrong type of property list") + + /* Get the plist structure */ + if(NULL == (plist = (H5P_genplist_t *)H5I_object(gapl_id))) + HGOTO_ERROR(H5E_SYM, H5E_BADATOM, FAIL, "can't find object for ID") + + /* Set up the properties for an asynchronous operation */ + if(H5FF_set_async_flag(plist, req) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTSET, FAIL, "can't set async request") + pl_modified = TRUE; + + + /* Perform the wrapped operation, possibly asynchronously */ + if((ret_value = H5Gopen2(loc_id, name, gapl_id)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to perform wrapped operation") + + + /* Retrieve async request from property, if non-NULL */ + if(req) + if(H5FF_get_async_req(plist, req) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't get async request") + +done: + if(pl_copied) { + if(H5Pclose(gapl_id) < 0) + HDONE_ERROR(H5E_SYM, H5E_CANTCLOSEOBJ, FAIL, "unable to close copied property list") + } /* end if */ + else if(pl_modified) { + /* Clear the async info from property list, if not copied */ + if(H5FF_reset_async_flag(plist) < 0) + HDONE_ERROR(H5E_SYM, H5E_CANTRESET, FAIL, "unable to reset modified property list") + } /* end if */ + + FUNC_LEAVE_API(ret_value) +} /* end H5Gopen_ff() */ + + +/*------------------------------------------------------------------------- + * Function: H5Dcreate_ff + * + * Purpose: Asynchronous wrapper around H5Dcreate(). + * + * Return: Success: The placeholder ID for a new dataset. When + * the asynchronous operation completes, this + * ID will transparently be modified to be a + * "normal" ID. + * Failure: FAIL + * + * Programmer: Quincey Koziol + * Wednesday, March 20, 2013 + * + *------------------------------------------------------------------------- + */ +hid_t +H5Dcreate_ff(hid_t loc_id, const char *name, hid_t type_id, + hid_t space_id, hid_t lcpl_id, hid_t dcpl_id, hid_t dapl_id, + uint64_t /* UNUSED */ trans, H5_request_t *req) +{ + H5P_genplist_t *plist; /* Property list pointer */ + hbool_t pl_copied = FALSE; /* Whether the property list was copied */ + hbool_t pl_modified = FALSE; /* Whether the property list was modified */ + hid_t ret_value; /* Return value */ + + FUNC_ENTER_API(FAIL) + + /* Get property list */ + if(H5P_DEFAULT == dapl_id) { + if((dapl_id = H5Pcopy(H5P_DATASET_ACCESS_DEFAULT)) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, FAIL, "can't copy default property list") + pl_copied = TRUE; + } /* end if */ + else + if(TRUE != H5P_isa_class(dapl_id, H5P_DATASET_ACCESS)) + HGOTO_ERROR(H5E_DATASET, H5E_BADTYPE, FAIL, "wrong type of property list") + + /* Get the plist structure */ + if(NULL == (plist = (H5P_genplist_t *)H5I_object(dapl_id))) + HGOTO_ERROR(H5E_DATASET, H5E_BADATOM, FAIL, "can't find object for ID") + + /* Set up the properties for an asynchronous operation */ + if(H5FF_set_async_flag(plist, req) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't set async request") + pl_modified = TRUE; + + + /* Perform the wrapped operation, possibly asynchronously */ + if((ret_value = H5Dcreate2(loc_id, name, type_id, space_id, lcpl_id, dcpl_id, dapl_id)) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCREATE, FAIL, "unable to perform wrapped operation") + + + /* Retrieve async request from property, if non-NULL */ + if(req) + if(H5FF_get_async_req(plist, req) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get async request") + +done: + if(pl_copied) { + if(H5Pclose(dapl_id) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CANTCLOSEOBJ, FAIL, "unable to close copied property list") + } /* end if */ + else if(pl_modified) { + /* Clear the async info from property list, if not copied */ + if(H5FF_reset_async_flag(plist) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CANTRESET, FAIL, "unable to reset modified property list") + } /* end if */ + + FUNC_LEAVE_API(ret_value) +} /* end H5Dcreate_ff() */ + + +/*------------------------------------------------------------------------- + * Function: H5Dopen_ff + * + * Purpose: Asynchronous wrapper around H5Dopen(). + * + * Return: Success: The placeholder ID for a dataset. When + * the asynchronous operation completes, this + * ID will transparently be modified to be a + * "normal" ID. + * Failure: FAIL + * + * Programmer: Quincey Koziol + * Wednesday, March 20, 2013 + * + *------------------------------------------------------------------------- + */ +hid_t +H5Dopen_ff(hid_t loc_id, const char *name, hid_t dapl_id, + uint64_t /* UNUSED */ trans, H5_request_t *req) +{ + H5P_genplist_t *plist; /* Property list pointer */ + hbool_t pl_copied = FALSE; /* Whether the property list was copied */ + hbool_t pl_modified = FALSE; /* Whether the property list was modified */ + hid_t ret_value; /* Return value */ + + FUNC_ENTER_API(FAIL) + + /* Get property list */ + if(H5P_DEFAULT == dapl_id) { + if((dapl_id = H5Pcopy(H5P_DATASET_ACCESS_DEFAULT)) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, FAIL, "can't copy default property list") + pl_copied = TRUE; + } /* end if */ + else + if(TRUE != H5P_isa_class(dapl_id, H5P_DATASET_ACCESS)) + HGOTO_ERROR(H5E_DATASET, H5E_BADTYPE, FAIL, "wrong type of property list") + + /* Get the plist structure */ + if(NULL == (plist = (H5P_genplist_t *)H5I_object(dapl_id))) + HGOTO_ERROR(H5E_DATASET, H5E_BADATOM, FAIL, "can't find object for ID") + + /* Set up the properties for an asynchronous operation */ + if(H5FF_set_async_flag(plist, req) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't set async request") + pl_modified = TRUE; + + + /* Perform the wrapped operation, possibly asynchronously */ + if((ret_value = H5Dopen2(loc_id, name, dapl_id)) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCREATE, FAIL, "unable to perform wrapped operation") + + + /* Retrieve async request from property, if non-NULL */ + if(req) + if(H5FF_get_async_req(plist, req) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get async request") + +done: + if(pl_copied) { + if(H5Pclose(dapl_id) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CANTCLOSEOBJ, FAIL, "unable to close copied property list") + } /* end if */ + else if(pl_modified) { + /* Clear the async info from property list, if not copied */ + if(H5FF_reset_async_flag(plist) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CANTRESET, FAIL, "unable to reset modified property list") + } /* end if */ + + FUNC_LEAVE_API(ret_value) +} /* end H5Dopen_ff() */ + + +/*------------------------------------------------------------------------- + * Function: H5Dwrite_ff + * + * Purpose: Asynchronous wrapper around H5Dwrite(). + * + * Return: Success: SUCCEED + * Failure: FAIL + * + * Programmer: Quincey Koziol + * Wednesday, March 20, 2013 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Dwrite_ff(hid_t dset_id, hid_t mem_type_id, hid_t mem_space_id, + hid_t file_space_id, hid_t dxpl_id, const void *buf, + uint64_t /* UNUSED */ trans, H5_request_t *req) +{ + H5P_genplist_t *plist; /* Property list pointer */ + hbool_t pl_copied = FALSE; /* Whether the property list was copied */ + hbool_t pl_modified = FALSE; /* Whether the property list was modified */ + herr_t ret_value; /* Return value */ + + FUNC_ENTER_API(FAIL) + + /* Get property list */ + if(H5P_DEFAULT == dxpl_id) { + if((dxpl_id = H5Pcopy(H5P_DATASET_XFER_DEFAULT)) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, FAIL, "can't copy default property list") + pl_copied = TRUE; + } /* end if */ + else + if(TRUE != H5P_isa_class(dxpl_id, H5P_DATASET_XFER)) + HGOTO_ERROR(H5E_DATASET, H5E_BADTYPE, FAIL, "wrong type of property list") + + /* Get the plist structure */ + if(NULL == (plist = (H5P_genplist_t *)H5I_object(dxpl_id))) + HGOTO_ERROR(H5E_DATASET, H5E_BADATOM, FAIL, "can't find object for ID") + + /* Set up the properties for an asynchronous operation */ + if(H5FF_set_async_flag(plist, req) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't set async request") + pl_modified = TRUE; + + + /* Perform the wrapped operation, possibly asynchronously */ + if((ret_value = H5Dwrite(dset_id, mem_type_id, mem_space_id, file_space_id, dxpl_id, buf)) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "unable to perform wrapped operation") + + + /* Retrieve async request from property, if non-NULL */ + if(req) + if(H5FF_get_async_req(plist, req) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get async request") + +done: + if(pl_copied) { + if(H5Pclose(dxpl_id) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CANTCLOSEOBJ, FAIL, "unable to close copied property list") + } /* end if */ + else if(pl_modified) { + /* Clear the async info from property list, if not copied */ + if(H5FF_reset_async_flag(plist) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CANTRESET, FAIL, "unable to reset modified property list") + } /* end if */ + + FUNC_LEAVE_API(ret_value) +} /* end H5Dwrite_ff() */ + + +/*------------------------------------------------------------------------- + * Function: H5Dread_ff + * + * Purpose: Asynchronous wrapper around H5Dread(). + * + * Return: Success: SUCCEED + * Failure: FAIL + * + * Programmer: Quincey Koziol + * Wednesday, March 20, 2013 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Dread_ff(hid_t dset_id, hid_t mem_type_id, hid_t mem_space_id, + hid_t file_space_id, hid_t dxpl_id, void *buf/*out*/, + uint64_t /* UNUSED */ trans, H5_request_t *req) +{ + H5P_genplist_t *plist; /* Property list pointer */ + hbool_t pl_copied = FALSE; /* Whether the property list was copied */ + hbool_t pl_modified = FALSE; /* Whether the property list was modified */ + herr_t ret_value; /* Return value */ + + FUNC_ENTER_API(FAIL) + + /* Get property list */ + if(H5P_DEFAULT == dxpl_id) { + if((dxpl_id = H5Pcopy(H5P_DATASET_XFER_DEFAULT)) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, FAIL, "can't copy default property list") + pl_copied = TRUE; + } /* end if */ + else + if(TRUE != H5P_isa_class(dxpl_id, H5P_DATASET_XFER)) + HGOTO_ERROR(H5E_DATASET, H5E_BADTYPE, FAIL, "wrong type of property list") + + /* Get the plist structure */ + if(NULL == (plist = (H5P_genplist_t *)H5I_object(dxpl_id))) + HGOTO_ERROR(H5E_DATASET, H5E_BADATOM, FAIL, "can't find object for ID") + + /* Set up the properties for an asynchronous operation */ + if(H5FF_set_async_flag(plist, req) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't set async request") + pl_modified = TRUE; + + + /* Perform the wrapped operation, possibly asynchronously */ + if((ret_value = H5Dread(dset_id, mem_type_id, mem_space_id, file_space_id, dxpl_id, buf)) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "unable to perform wrapped operation") + + + /* Retrieve async request from property, if non-NULL */ + if(req) + if(H5FF_get_async_req(plist, req) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get async request") + +done: + if(pl_copied) { + if(H5Pclose(dxpl_id) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CANTCLOSEOBJ, FAIL, "unable to close copied property list") + } /* end if */ + else if(pl_modified) { + /* Clear the async info from property list, if not copied */ + if(H5FF_reset_async_flag(plist) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CANTRESET, FAIL, "unable to reset modified property list") + } /* end if */ + + FUNC_LEAVE_API(ret_value) +} /* end H5Dread_ff() */ + + +/*------------------------------------------------------------------------- + * Function: H5AOtest + * + * Purpose: Test for an asynchronous operation's completion + * + * Return: Success: SUCCEED + * Failure: FAIL + * + * Programmer: Quincey Koziol + * Wednesday, March 20, 2013 + * + *------------------------------------------------------------------------- + */ +herr_t +H5AOtest(H5_request_t *req, H5_status_t *status) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + +/* I believe that the VOL interface needs to be expanded with a 'test' callback, + since the H5_request_t is pointing at a H5VL_iod_request_t [currently] + and I can't get down to the VOL plugin from here. + + [And the 'test' client callback needs to release the request structure that + the plugin allocated, if the operation has completed] +*/ + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5AOtest() */ + + +/*------------------------------------------------------------------------- + * Function: H5AOwait + * + * Purpose: Wait for an asynchronous operation to complete + * + * Return: Success: SUCCEED + * Failure: FAIL + * + * Programmer: Quincey Koziol + * Wednesday, March 20, 2013 + * + *------------------------------------------------------------------------- + */ +herr_t +H5AOwait(H5_request_t *req, H5_status_t *status) +{ + H5VL_iod_request_t *request = *((H5VL_iod_request_t **)req); + fs_status_t tmp_status; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + + if(H5VL_IOD_PENDING == request->state) { + if(H5VL_iod_request_wait(request->obj->file, request) < 0) + HDONE_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "unable to wait for request") + } + *status = request->status; + +#if 0 + + fs_wait(*((fs_request_t *)request->req), FS_MAX_IDLE_TIME, &tmp_status); + if(tmp_status) + *status = H5AO_SUCCEEDED; + else + *status = H5AO_FAILED; + } + else if(H5VL_IOD_COMPLETED == request->state) { + *status = request->status; + } +#endif + + request->req = H5MM_xfree(request->req); + request = H5MM_xfree(request); + req = NULL; + +/* I believe that the VOL interface needs to be expanded with a 'wait' callback, + since the H5_request_t is pointing at a H5VL_iod_request_t [currently] + and I can't get down to the VOL plugin from here. + + [And the 'wait' client callback needs to release the request structure that + the plugin allocated] +*/ + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5AOwait() */ + diff --git a/src/H5FFprivate.h b/src/H5FFprivate.h new file mode 100644 index 0000000..c10f8f4 --- /dev/null +++ b/src/H5FFprivate.h @@ -0,0 +1,49 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the files COPYING and Copyright.html. COPYING can be found at the root * + * of the source code distribution tree; Copyright.html can be found at the * + * root level of an installed copy of the electronic HDF5 document set and * + * is linked from the top-level documents page. It can also be found at * + * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * + * access to either file, you may request a copy from help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * This file contains private information about the H5FF module + */ +#ifndef _H5FFprivate_H +#define _H5FFprivate_H + +/* Include package's public header */ +#include "H5FFpublic.h" + +/* Private headers needed by this file */ +#include "H5private.h" /* Generic Functions */ + + +/**************************/ +/* Library Private Macros */ +/**************************/ + + +/****************************/ +/* Library Private Typedefs */ +/****************************/ + + +/*****************************/ +/* Library Private Variables */ +/*****************************/ + + +/******************************/ +/* Library Private Prototypes */ +/******************************/ + + +#endif /* _H5FFprivate_H */ + diff --git a/src/H5FFpublic.h b/src/H5FFpublic.h new file mode 100644 index 0000000..ab52616 --- /dev/null +++ b/src/H5FFpublic.h @@ -0,0 +1,91 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the files COPYING and Copyright.html. COPYING can be found at the root * + * of the source code distribution tree; Copyright.html can be found at the * + * root level of an installed copy of the electronic HDF5 document set and * + * is linked from the top-level documents page. It can also be found at * + * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * + * access to either file, you may request a copy from help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * This file contains function prototypes for each exported function in the + * H5FF module. + */ +#ifndef _H5FFpublic_H +#define _H5FFpublic_H + +/* System headers needed by this file */ + +/* Public headers needed by this file */ + + +/*****************/ +/* Public Macros */ +/*****************/ + +#ifdef __cplusplus +extern "C" { +#endif + +/*******************/ +/* Public Typedefs */ +/*******************/ + +/* An asynchronous request object */ +typedef void *H5_request_t; + +/* Asynchronous operation status */ +typedef enum { + H5AO_PENDING, /* Operation has not yet completed */ + H5AO_SUCCEEDED, /* Operation has completed, successfully */ + H5AO_FAILED /* Operation has completed, but failed */ +} H5_status_t; + + +/********************/ +/* Public Variables */ +/********************/ + + +/*********************/ +/* Public Prototypes */ +/*********************/ + +/* API wrappers */ +H5_DLL hid_t H5Fcreate_ff(const char *filename, unsigned flags, hid_t fcpl, + hid_t fapl, + H5_request_t *req); +H5_DLL hid_t H5Fopen_ff(const char *filename, unsigned flags, hid_t fapl_id, + H5_request_t *req); +H5_DLL hid_t H5Gcreate_ff(hid_t loc_id, const char *name, hid_t lcpl_id, + hid_t gcpl_id, hid_t gapl_id, + uint64_t /* UNUSED */ trans, H5_request_t *req); +H5_DLL hid_t H5Gopen_ff(hid_t loc_id, const char *name, hid_t gapl_id, + uint64_t /* UNUSED */ trans, H5_request_t *req); +H5_DLL hid_t H5Dcreate_ff(hid_t loc_id, const char *name, hid_t type_id, + hid_t space_id, hid_t lcpl_id, hid_t dcpl_id, hid_t dapl_id, + uint64_t /* UNUSED */ trans, H5_request_t *req); +H5_DLL hid_t H5Dopen_ff(hid_t loc_id, const char *name, hid_t dapl_id, + uint64_t /* UNUSED */ trans, H5_request_t *req); +H5_DLL herr_t H5Dwrite_ff(hid_t dset_id, hid_t mem_type_id, hid_t mem_space_id, + hid_t file_space_id, hid_t dxpl_id, const void *buf, + uint64_t /* UNUSED */ trans, H5_request_t *req); +H5_DLL herr_t H5Dread_ff(hid_t dset_id, hid_t mem_type_id, hid_t mem_space_id, + hid_t file_space_id, hid_t dxpl_id, void *buf/*out*/, + uint64_t /* UNUSED */ trans, H5_request_t *req); + +/* Asynchronous test & wait operations */ +H5_DLL herr_t H5AOtest(H5_request_t *req, H5_status_t *status); +H5_DLL herr_t H5AOwait(H5_request_t *req, H5_status_t *status); + + +#ifdef __cplusplus +} +#endif +#endif /* _H5FFpublic_H */ + diff --git a/src/H5Pdxpl.c b/src/H5Pdxpl.c index da0c214..a83df90 100644 --- a/src/H5Pdxpl.c +++ b/src/H5Pdxpl.c @@ -49,8 +49,8 @@ #define H5D_XFER_INJECT_BAD_CHECKSUM_SIZE sizeof(hbool_t) #define H5D_XFER_INJECT_BAD_CHECKSUM_DEF FALSE -#define H5D_XFER_INJECT_BAD_CHECKSUM_ENC H5P__encode_unsigned -#define H5D_XFER_INJECT_BAD_CHECKSUM_DEC H5P__decode_unsigned +#define H5D_XFER_INJECT_BAD_CHECKSUM_ENC H5P__encode_hbool_t +#define H5D_XFER_INJECT_BAD_CHECKSUM_DEC H5P__decode_hbool_t /* ======== Data transfer properties ======== */ /* Definitions for maximum temp buffer size property */ diff --git a/src/H5Pint.c b/src/H5Pint.c index 52db9d5..aa7ad21 100644 --- a/src/H5Pint.c +++ b/src/H5Pint.c @@ -43,6 +43,11 @@ /* Local Macros */ /****************/ +/* Async. I/O properties */ +#define H5P_ASYNC_FLAG_SIZE sizeof(hbool_t) +#define H5P_ASYNC_REQ_SIZE sizeof(void *) +#define H5P_ASYNC_REQ_DEF NULL + /******************/ /* Local Typedefs */ @@ -89,6 +94,9 @@ static H5P_genprop_t *H5P_dup_prop(H5P_genprop_t *oprop, H5P_prop_within_t type) static herr_t H5P_free_prop(H5P_genprop_t *prop); static int H5P_cmp_prop(const H5P_genprop_t *prop1, const H5P_genprop_t *prop2); +/* Property class callbacks */ +static herr_t H5P__root_reg_prop(H5P_genclass_t *pclass); + /*********************/ /* Package Variables */ @@ -142,7 +150,7 @@ const H5P_libclass_t H5P_CLS_ROOT[1] = {{ NULL, /* Parent class ID */ &H5P_CLS_ROOT_g, /* Pointer to class ID */ NULL, /* Pointer to default property list ID */ - NULL, /* Default property registration routine */ + H5P__root_reg_prop, /* Default property registration routine */ NULL, /* Class creation callback */ NULL, /* Class creation callback info */ NULL, /* Class copy callback */ @@ -285,6 +293,10 @@ static const H5I_class_t H5I_GENPROPLST_CLS[1] = {{ NULL /* Callback routine for closing auxilary objects of this class */ }}; +/* Property value defaults */ +static const hbool_t H5_def_async_flag_g = H5P_ASYNC_FLAG_DEF; /* Default async flag */ +static const void *H5_def_async_req_g = H5P_ASYNC_REQ_DEF; /* Default async request pointer */ + /*-------------------------------------------------------------------------- @@ -385,6 +397,42 @@ done: } /* end H5P_init() */ +/*------------------------------------------------------------------------- + * Function: H5P__root_reg_prop + * + * Purpose: Initialize the root property list class + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * March 20, 2013 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5P__root_reg_prop(H5P_genclass_t *pclass) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + /* Register async. flag property */ + if(H5P_register_real(pclass, H5P_ASYNC_FLAG_NAME, H5P_ASYNC_FLAG_SIZE, &H5_def_async_flag_g, + NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") + + /* Register async. request property */ + if(H5P_register_real(pclass, H5P_ASYNC_REQ_NAME, H5P_ASYNC_REQ_SIZE, &H5_def_async_req_g, + NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5P__root_reg_prop() */ + + /*-------------------------------------------------------------------------- NAME H5P_init_interface -- Initialize interface-specific information diff --git a/src/H5Pprivate.h b/src/H5Pprivate.h index 3835a16..fe3293f 100644 --- a/src/H5Pprivate.h +++ b/src/H5Pprivate.h @@ -35,6 +35,11 @@ /* ======== String creation property names ======== */ #define H5P_STRCRT_CHAR_ENCODING_NAME "character_encoding" /* Character set encoding for string */ +/* ======== Root property names ======== */ +#define H5P_ASYNC_FLAG_NAME "async flag" /* Async flag */ +#define H5P_ASYNC_FLAG_DEF FALSE +#define H5P_ASYNC_REQ_NAME "async request" /* Async request */ + /****************************/ /* Library Private Typedefs */ diff --git a/src/H5VLiod.c b/src/H5VLiod.c index 055ba50..88b611d 100644 --- a/src/H5VLiod.c +++ b/src/H5VLiod.c @@ -550,9 +550,12 @@ H5VL_iod_file_create(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl H5P_genplist_t *plist; /* Property list pointer */ int my_rank, my_size; H5VL_iod_file_t *file = NULL; - fs_request_t *fs_req; - H5VL_iod_request_t *request; + fs_request_t _fs_req; /* Local function shipper request, for sync. operations */ + fs_request_t *fs_req = NULL; + H5VL_iod_request_t _request; /* Local request, for sync. operations */ + H5VL_iod_request_t *request = NULL; H5VL_iod_file_create_input_t input; + hbool_t do_async; /* Whether we're performing async. I/O */ void *ret_value = NULL; FUNC_ENTER_NOAPI_NOINIT @@ -584,28 +587,22 @@ H5VL_iod_file_create(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl input.fcpl_id = fcpl_id; input.fapl_id = fapl_id; - /* allocate a function shipper request */ - if(NULL == (fs_req = (fs_request_t *)H5MM_malloc(sizeof(fs_request_t)))) - HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, NULL, "can't allocate a FS request"); + /* Get async flag */ + if(H5P_get(plist, H5P_ASYNC_FLAG_NAME, &do_async) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get property value for lcpl id"); + + /* get a function shipper request */ + if(do_async) { + if(NULL == (fs_req = (fs_request_t *)H5MM_malloc(sizeof(fs_request_t)))) + HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, NULL, "can't allocate a FS request"); + } /* end if */ + else + fs_req = &_fs_req; /* forward the call to the ION */ if(fs_forward(PEER, H5VL_FILE_CREATE_ID, &input, &file->remote_file, fs_req) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "failed to ship file create"); - /* initialize head and tail of the container's linked list */ - file->request_list_head = NULL; - file->request_list_tail = NULL; - - /* setup a request to track completion of the operation */ - if(NULL == (request = (H5VL_iod_request_t *)H5MM_malloc(sizeof(H5VL_iod_request_t)))) - HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, NULL, "can't allocate IOD VOL request struct"); - request->type = FS_FILE_CREATE; - request->data = file; - request->req = fs_req; - request->next = request->prev = NULL; - /* add request to container's linked list */ - H5VL_iod_request_add(file, request); - /* create the file object that is passed to the API layer */ file->file_name = HDstrdup(name); file->flags = flags; @@ -615,12 +612,57 @@ H5VL_iod_file_create(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl HGOTO_ERROR(H5E_SYM, H5E_CANTCOPY, NULL, "failed to copy fapl"); file->nopen_objs = 1; + /* initialize head and tail of the container's linked list of requests */ + file->request_list_head = NULL; + file->request_list_tail = NULL; + file->common.obj_type = H5I_FILE; /* The name of the location is the root's object name "\" */ file->common.obj_name = strdup("/"); file->common.obj_name[1] = '\0'; file->common.file = file; - file->common.request = request; + + /* Get async request for operation */ + if(do_async) { + if(NULL == (request = (H5VL_iod_request_t *)H5MM_malloc(sizeof(H5VL_iod_request_t)))) + HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, NULL, "can't allocate IOD VOL request struct"); + } /* end if */ + else + request = &_request; + + /* Set up request */ + HDmemset(request, 0, sizeof(*request)); + request->type = FS_FILE_CREATE; + request->data = file; + request->req = fs_req; + request->obj = file; + request->next = request->prev = NULL; + /* add request to container's linked list */ + H5VL_iod_request_add(file, request); + + /* Store/wait on request */ + if(do_async) { + /* Sanity check */ + HDassert(request != &_request); + + /* Set async. request property, for higher layer to retrieve */ + if(H5P_set(plist, H5P_ASYNC_REQ_NAME, &request) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTSET, NULL, "unable to set request"); + + /* Track request */ + file->common.request = request; + } /* end if */ + else { + /* Synchronously wait on the request */ + if(H5VL_iod_request_wait(file, request) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "can't wait on FS request"); + + /* Sanity check */ + HDassert(request == &_request); + + /* Request has completed already */ + file->common.request = NULL; + } /* end else */ ret_value = (void *)file; @@ -649,9 +691,12 @@ H5VL_iod_file_open(const char *name, unsigned flags, hid_t fapl_id, hid_t UNUSED H5P_genplist_t *plist; /* Property list pointer */ int my_rank, my_size; H5VL_iod_file_t *file = NULL; - fs_request_t *fs_req; - H5VL_iod_request_t *request; + fs_request_t _fs_req; /* Local function shipper request, for sync. operations */ + fs_request_t *fs_req = NULL; + H5VL_iod_request_t _request; /* Local request, for sync. operations */ + H5VL_iod_request_t *request = NULL; H5VL_iod_file_open_input_t input; + hbool_t do_async; /* Whether we're performing async. I/O */ void *ret_value = NULL; FUNC_ENTER_NOAPI_NOINIT @@ -673,28 +718,22 @@ H5VL_iod_file_open(const char *name, unsigned flags, hid_t fapl_id, hid_t UNUSED input.flags = flags; input.fapl_id = fapl_id; - /* allocate a function shipper request */ - if(NULL == (fs_req = (fs_request_t *)H5MM_malloc(sizeof(fs_request_t)))) - HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, NULL, "can't allocate a FS request"); + /* Get async flag */ + if(H5P_get(plist, H5P_ASYNC_FLAG_NAME, &do_async) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get property value for lcpl id"); + + /* get a function shipper request */ + if(do_async) { + if(NULL == (fs_req = (fs_request_t *)H5MM_malloc(sizeof(fs_request_t)))) + HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, NULL, "can't allocate a FS request"); + } /* end if */ + else + fs_req = &_fs_req; /* forward the call to the server */ if(fs_forward(PEER, H5VL_FILE_OPEN_ID, &input, &file->remote_file, fs_req) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "failed to ship file create"); - /* initialize head and tail of the container's linked list */ - file->request_list_head = NULL; - file->request_list_tail = NULL; - - /* setup a request to track completion of the operation */ - if(NULL == (request = (H5VL_iod_request_t *)H5MM_malloc(sizeof(H5VL_iod_request_t)))) - HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, NULL, "can't allocate IOD VOL request struct"); - request->type = FS_FILE_OPEN; - request->data = file; - request->req = fs_req; - request->next = request->prev = NULL; - /* add request to container's linked list */ - H5VL_iod_request_add(file, request); - /* create the file object that is passed to the API layer */ file->file_name = HDstrdup(name); file->flags = flags; @@ -702,12 +741,57 @@ H5VL_iod_file_open(const char *name, unsigned flags, hid_t fapl_id, hid_t UNUSED HGOTO_ERROR(H5E_SYM, H5E_CANTCOPY, NULL, "failed to copy fapl"); file->nopen_objs = 1; + /* initialize head and tail of the container's linked list */ + file->request_list_head = NULL; + file->request_list_tail = NULL; + file->common.obj_type = H5I_FILE; /* The name of the location is the root's object name "\" */ file->common.obj_name = strdup("/"); file->common.obj_name[1] = '\0'; file->common.file = file; - file->common.request = request; + + /* Get async request for operation */ + if(do_async) { + if(NULL == (request = (H5VL_iod_request_t *)H5MM_malloc(sizeof(H5VL_iod_request_t)))) + HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, NULL, "can't allocate IOD VOL request struct"); + } /* end if */ + else + request = &_request; + + /* Set up request */ + HDmemset(request, 0, sizeof(*request)); + request->type = FS_FILE_OPEN; + request->data = file; + request->req = fs_req; + request->obj = file; + request->next = request->prev = NULL; + /* add request to container's linked list */ + H5VL_iod_request_add(file, request); + + /* Store/wait on request */ + if(do_async) { + /* Sanity check */ + HDassert(request != &_request); + + /* Set async. request property, for higher layer to retrieve */ + if(H5P_set(plist, H5P_ASYNC_REQ_NAME, &request) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTSET, NULL, "unable to set request") + + /* Track request */ + file->common.request = request; + } /* end if */ + else { + /* Synchronously wait on the request */ + if(H5VL_iod_request_wait(file, request) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "can't wait on FS request"); + + /* Sanity check */ + HDassert(request == &_request); + + /* Request has completed already */ + file->common.request = NULL; + } /* end else */ ret_value = (void *)file; @@ -734,10 +818,12 @@ H5VL_iod_file_flush(void *_obj, H5VL_loc_params_t loc_params, H5F_scope_t scope, { H5VL_iod_object_t *obj = (H5VL_iod_object_t *)_obj; H5VL_iod_file_t *file = obj->file; - fs_request_t *fs_req; + fs_request_t _fs_req; /* Local function shipper request, for sync. operations */ + fs_request_t *fs_req = &_fs_req; int *status; H5VL_iod_file_flush_input_t input; - H5VL_iod_request_t *request; + H5VL_iod_request_t _request; /* Local request, for sync. operations */ + H5VL_iod_request_t *request = &_request; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT @@ -746,10 +832,6 @@ H5VL_iod_file_flush(void *_obj, H5VL_loc_params_t loc_params, H5F_scope_t scope, if(H5VL_iod_request_wait_all(file) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't wait on FS requests"); - /* allocate a function shipper request */ - if(NULL == (fs_req = (fs_request_t *)H5MM_malloc(sizeof(fs_request_t)))) - HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, FAIL, "can't allocate a FS request"); - /* set the input structure for the FS encode routine */ input.coh = file->remote_file.coh; input.scope = scope; @@ -761,16 +843,23 @@ H5VL_iod_file_flush(void *_obj, H5VL_loc_params_t loc_params, H5F_scope_t scope, if(fs_forward(PEER, H5VL_FILE_FLUSH_ID, &input, status, fs_req) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "failed to ship file close"); - /* setup a request to track completion of the operation */ - if(NULL == (request = (H5VL_iod_request_t *)H5MM_malloc(sizeof(H5VL_iod_request_t)))) - HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, FAIL, "can't allocate IOD VOL request struct"); + /* Set up request */ + HDmemset(request, 0, sizeof(*request)); request->type = FS_FILE_FLUSH; request->data = status; request->req = fs_req; + request->obj = file; request->next = request->prev = NULL; /* add request to container's linked list */ H5VL_iod_request_add(file, request); + /* Synchronously wait on the request (no way to return request object currently) */ + if(H5VL_iod_request_wait(file, request) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't wait on FS request"); + if(SUCCEED != *status) + HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "file flush failed at the server") + free(status); + done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5VL_iod_file_flush() */ @@ -995,9 +1084,11 @@ static herr_t H5VL_iod_file_close(void *_file, hid_t UNUSED req) { H5VL_iod_file_t *file = (H5VL_iod_file_t *)_file; - fs_request_t *fs_req; + fs_request_t _fs_req; /* Local function shipper request, for sync. operations */ + fs_request_t *fs_req = &_fs_req; int *status; - H5VL_iod_request_t *request; + H5VL_iod_request_t _request; /* Local request, for sync. operations */ + H5VL_iod_request_t *request = &_request; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT @@ -1006,10 +1097,6 @@ H5VL_iod_file_close(void *_file, hid_t UNUSED req) if(H5VL_iod_request_wait_all(file) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't wait on FS requests"); - /* allocate a function shipper request */ - if(NULL == (fs_req = (fs_request_t *)H5MM_malloc(sizeof(fs_request_t)))) - HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, FAIL, "can't allocate a FS request"); - /* allocate an integer to receive the return value if the file close succeeded or not */ status = (int *)malloc(sizeof(int)); @@ -1017,12 +1104,12 @@ H5VL_iod_file_close(void *_file, hid_t UNUSED req) if(fs_forward(PEER, H5VL_FILE_CLOSE_ID, &file->remote_file, status, fs_req) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "failed to ship file close"); - /* setup a request to track completion of the operation */ - if(NULL == (request = (H5VL_iod_request_t *)H5MM_malloc(sizeof(H5VL_iod_request_t)))) - HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, FAIL, "can't allocate IOD VOL request struct"); + /* Set up request */ + HDmemset(request, 0, sizeof(*request)); request->type = FS_FILE_CLOSE; request->data = status; request->req = fs_req; + request->obj = file; request->next = request->prev = NULL; /* add request to container's linked list */ H5VL_iod_request_add(file, request); @@ -1032,6 +1119,7 @@ H5VL_iod_file_close(void *_file, hid_t UNUSED req) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't wait on FS request"); if(SUCCEED != *status) HGOTO_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "File close failed at the server"); + free(status); /* free everything */ free(file->file_name); @@ -1042,8 +1130,6 @@ H5VL_iod_file_close(void *_file, hid_t UNUSED req) HGOTO_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "failed to close plist"); file = H5FL_FREE(H5VL_iod_file_t, file); - free(status); - done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5VL_iod_file_close() */ @@ -1074,13 +1160,16 @@ H5VL_iod_group_create(void *_obj, H5VL_loc_params_t loc_params, const char *name iod_obj_id_t iod_id; iod_handle_t iod_oh; char *new_name; - fs_request_t *fs_req; - H5VL_iod_request_t *request; + fs_request_t _fs_req; /* Local function shipper request, for sync. operations */ + fs_request_t *fs_req = NULL; + H5VL_iod_request_t _request; /* Local request, for sync. operations */ + H5VL_iod_request_t *request = NULL; + hbool_t do_async; /* Whether we're performing async. I/O */ void *ret_value = NULL; FUNC_ENTER_NOAPI_NOINIT - /* Get the plist structure */ + /* Get the group creation plist structure */ if(NULL == (plist = (H5P_genplist_t *)H5I_object(gcpl_id))) HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, NULL, "can't find object for ID"); @@ -1107,24 +1196,26 @@ H5VL_iod_group_create(void *_obj, H5VL_loc_params_t loc_params, const char *name input.gapl_id = gapl_id; input.lcpl_id = lcpl_id; - /* allocate a function shipper request */ - if(NULL == (fs_req = (fs_request_t *)H5MM_malloc(sizeof(fs_request_t)))) - HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, NULL, "can't allocate a FS request"); + /* Get the group access plist structure */ + if(NULL == (plist = (H5P_genplist_t *)H5I_object(gapl_id))) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, NULL, "can't find object for ID"); + + /* Get async flag */ + if(H5P_get(plist, H5P_ASYNC_FLAG_NAME, &do_async) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get property value for lcpl id"); + + /* get a function shipper request */ + if(do_async) { + if(NULL == (fs_req = (fs_request_t *)H5MM_malloc(sizeof(fs_request_t)))) + HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, NULL, "can't allocate a FS request"); + } /* end if */ + else + fs_req = &_fs_req; /* forward the call to the IONs */ if(fs_forward(PEER, H5VL_GROUP_CREATE_ID, &input, &grp->remote_group, fs_req) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "failed to ship group create"); - /* setup a request to track completion of the operation */ - if(NULL == (request = (H5VL_iod_request_t *)H5MM_malloc(sizeof(H5VL_iod_request_t)))) - HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, NULL, "can't allocate IOD VOL request struct"); - request->type = FS_GROUP_CREATE; - request->data = grp; - request->req = fs_req; - request->next = request->prev = NULL; - /* add request to container's linked list */ - H5VL_iod_request_add(obj->file, request); - /* setup the local group struct */ /* store the entire path of the group locally */ if (NULL == (grp->common.obj_name = (char *)malloc @@ -1143,7 +1234,48 @@ H5VL_iod_group_create(void *_obj, H5VL_loc_params_t loc_params, const char *name grp->common.obj_type = H5I_GROUP; grp->common.file = obj->file; grp->common.file->nopen_objs ++; - grp->common.request = request; + + /* Get async request for operation */ + if(do_async) { + if(NULL == (request = (H5VL_iod_request_t *)H5MM_malloc(sizeof(H5VL_iod_request_t)))) + HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, NULL, "can't allocate IOD VOL request struct"); + } /* end if */ + else + request = &_request; + + /* Set up request */ + HDmemset(request, 0, sizeof(*request)); + request->type = FS_GROUP_CREATE; + request->data = grp; + request->req = fs_req; + request->obj = grp; + request->next = request->prev = NULL; + /* add request to container's linked list */ + H5VL_iod_request_add(obj->file, request); + + /* Store/wait on request */ + if(do_async) { + /* Sanity check */ + HDassert(request != &_request); + + /* Set async. request property, for higher layer to retrieve */ + if(H5P_set(plist, H5P_ASYNC_REQ_NAME, &request) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTSET, NULL, "unable to set request") + + /* Track request */ + grp->common.request = request; + } /* end if */ + else { + /* Synchronously wait on the request */ + if(H5VL_iod_request_wait(obj->file, request) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, NULL, "can't wait on FS request") + + /* Sanity check */ + HDassert(request == &_request); + + /* Request has completed already */ + grp->common.request = NULL; + } /* end else */ ret_value = (void *)grp; @@ -1172,11 +1304,15 @@ H5VL_iod_group_open(void *_obj, H5VL_loc_params_t loc_params, const char *name, { H5VL_iod_object_t *obj = (H5VL_iod_object_t *)_obj; /* location object to create the group */ H5VL_iod_group_t *grp = NULL; /* the group object that is created and passed to the user */ + H5P_genplist_t *plist; iod_obj_id_t iod_id; iod_handle_t iod_oh; char *new_name; - fs_request_t *fs_req; - H5VL_iod_request_t *request; + fs_request_t _fs_req; /* Local function shipper request, for sync. operations */ + fs_request_t *fs_req = NULL; + H5VL_iod_request_t _request; /* Local request, for sync. operations */ + H5VL_iod_request_t *request = NULL; + hbool_t do_async; /* Whether we're performing async. I/O */ H5VL_iod_group_open_input_t input; void *ret_value = NULL; @@ -1199,24 +1335,26 @@ H5VL_iod_group_open(void *_obj, H5VL_loc_params_t loc_params, const char *name, input.name = new_name; input.gapl_id = gapl_id; - /* allocate a function shipper request */ - if(NULL == (fs_req = (fs_request_t *)H5MM_malloc(sizeof(fs_request_t)))) - HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, NULL, "can't allocate a FS request"); + /* Get the group access plist structure */ + if(NULL == (plist = (H5P_genplist_t *)H5I_object(gapl_id))) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, NULL, "can't find object for ID"); + + /* Get async flag */ + if(H5P_get(plist, H5P_ASYNC_FLAG_NAME, &do_async) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get property value for lcpl id"); + + /* get a function shipper request */ + if(do_async) { + if(NULL == (fs_req = (fs_request_t *)H5MM_malloc(sizeof(fs_request_t)))) + HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, NULL, "can't allocate a FS request"); + } /* end if */ + else + fs_req = &_fs_req; /* forward the call to the IONs */ if(fs_forward(PEER, H5VL_GROUP_OPEN_ID, &input, &grp->remote_group, fs_req) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "failed to ship group open"); - /* setup a request to track completion of the operation */ - if(NULL == (request = (H5VL_iod_request_t *)H5MM_malloc(sizeof(H5VL_iod_request_t)))) - HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, NULL, "can't allocate IOD VOL request struct"); - request->type = FS_GROUP_OPEN; - request->data = grp; - request->req = fs_req; - request->next = request->prev = NULL; - /* add request to container's linked list */ - H5VL_iod_request_add(obj->file, request); - /* setup the local group struct */ /* store the entire path of the group locally */ if (NULL == (grp->common.obj_name = (char *)malloc @@ -1233,7 +1371,48 @@ H5VL_iod_group_open(void *_obj, H5VL_loc_params_t loc_params, const char *name, grp->common.obj_type = H5I_GROUP; grp->common.file = obj->file; grp->common.file->nopen_objs ++; - grp->common.request = request; + + /* Get async request for operation */ + if(do_async) { + if(NULL == (request = (H5VL_iod_request_t *)H5MM_malloc(sizeof(H5VL_iod_request_t)))) + HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, NULL, "can't allocate IOD VOL request struct"); + } /* end if */ + else + request = &_request; + + /* Set up request */ + HDmemset(request, 0, sizeof(*request)); + request->type = FS_GROUP_OPEN; + request->data = grp; + request->req = fs_req; + request->obj = grp; + request->next = request->prev = NULL; + /* add request to container's linked list */ + H5VL_iod_request_add(obj->file, request); + + /* Store/wait on request */ + if(do_async) { + /* Sanity check */ + HDassert(request != &_request); + + /* Set async. request property, for higher layer to retrieve */ + if(H5P_set(plist, H5P_ASYNC_REQ_NAME, &request) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTSET, NULL, "unable to set request") + + /* Track request */ + grp->common.request = request; + } /* end if */ + else { + /* Synchronously wait on the request */ + if(H5VL_iod_request_wait(obj->file, request) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, NULL, "can't wait on FS request") + + /* Sanity check */ + HDassert(request == &_request); + + /* Request has completed already */ + grp->common.request = NULL; + } /* end else */ ret_value = (void *)grp; @@ -1306,9 +1485,11 @@ static herr_t H5VL_iod_group_close(void *_grp, hid_t UNUSED req) { H5VL_iod_group_t *grp = (H5VL_iod_group_t *)_grp; - fs_request_t *fs_req; + fs_request_t _fs_req; /* Local function shipper request, for sync. operations */ + fs_request_t *fs_req = &_fs_req; int *status; - H5VL_iod_request_t *request; + H5VL_iod_request_t _request; /* Local request, for sync. operations */ + H5VL_iod_request_t *request = &_request; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT @@ -1317,13 +1498,13 @@ H5VL_iod_group_close(void *_grp, hid_t UNUSED req) if(NULL != grp->common.request) { if(H5VL_iod_request_wait(grp->common.file, grp->common.request) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't wait on FS request"); - grp->common.request->req = H5MM_xfree(grp->common.request->req); - grp->common.request = H5MM_xfree(grp->common.request); - } - /* allocate a function shipper request */ - if(NULL == (fs_req = (fs_request_t *)H5MM_malloc(sizeof(fs_request_t)))) - HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, FAIL, "can't allocate a FS request"); + /* Reset object's pointer to request */ + /* (Request is owned by the request object and will be freed when the + * application calls test or wait on it.) + */ + grp->common.request = NULL; + } /* allocate an integer to receive the return value if the group close succeeded or not */ status = (int *)malloc(sizeof(int)); @@ -1332,16 +1513,23 @@ H5VL_iod_group_close(void *_grp, hid_t UNUSED req) if(fs_forward(PEER, H5VL_GROUP_CLOSE_ID, &grp->remote_group, status, fs_req) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "failed to ship group close"); - /* setup a request to track completion of the operation */ - if(NULL == (request = (H5VL_iod_request_t *)H5MM_malloc(sizeof(H5VL_iod_request_t)))) - HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, FAIL, "can't allocate IOD VOL request struct"); + /* Set up request */ + HDmemset(request, 0, sizeof(*request)); request->type = FS_GROUP_CLOSE; request->data = status; request->req = fs_req; + request->obj = grp; request->next = request->prev = NULL; /* add request to container's linked list */ H5VL_iod_request_add(grp->common.file, request); + /* Synchronously wait on the request (no way to return request object currently) */ + if(H5VL_iod_request_wait(grp->common.file, request) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't wait on FS request"); + if(SUCCEED != *status) + HGOTO_ERROR(H5E_SYM, H5E_CANTCLOSEOBJ, FAIL, "group close failed at the server") + free(status); + free(grp->common.obj_name); if(H5Pclose(grp->gapl_id) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "failed to close plist"); @@ -1378,9 +1566,12 @@ H5VL_iod_dataset_create(void *_obj, H5VL_loc_params_t loc_params, const char *na iod_obj_id_t iod_id; iod_handle_t iod_oh; char *new_name; - fs_request_t *fs_req; - H5VL_iod_request_t *request; + fs_request_t _fs_req; /* Local function shipper request, for sync. operations */ + fs_request_t *fs_req = NULL; + H5VL_iod_request_t _request; /* Local request, for sync. operations */ + H5VL_iod_request_t *request = NULL; hid_t type_id, space_id, lcpl_id; + hbool_t do_async; /* Whether we're performing async. I/O */ void *ret_value = NULL; FUNC_ENTER_NOAPI_NOINIT @@ -1418,24 +1609,26 @@ H5VL_iod_dataset_create(void *_obj, H5VL_loc_params_t loc_params, const char *na input.type_id = type_id; input.space_id = space_id; - /* allocate a function shipper request */ - if(NULL == (fs_req = (fs_request_t *)H5MM_malloc(sizeof(fs_request_t)))) - HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, NULL, "can't allocate a FS request"); + /* Get the dapl plist structure */ + if(NULL == (plist = (H5P_genplist_t *)H5I_object(dapl_id))) + HGOTO_ERROR(H5E_DATASET, H5E_BADATOM, NULL, "can't find object for ID") + + /* Get async flag */ + if(H5P_get(plist, H5P_ASYNC_FLAG_NAME, &do_async) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, NULL, "can't get property value for lcpl id"); + + /* get a function shipper request */ + if(do_async) { + if(NULL == (fs_req = (fs_request_t *)H5MM_malloc(sizeof(fs_request_t)))) + HGOTO_ERROR(H5E_DATASET, H5E_NOSPACE, NULL, "can't allocate a FS request"); + } /* end if */ + else + fs_req = &_fs_req; /* forward the call to the IONs */ if(fs_forward(PEER, H5VL_DSET_CREATE_ID, &input, &dset->remote_dset, fs_req) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "failed to ship dataset create"); - /* setup a request to track completion of the operation */ - if(NULL == (request = (H5VL_iod_request_t *)H5MM_malloc(sizeof(H5VL_iod_request_t)))) - HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, NULL, "can't allocate IOD VOL request struct"); - request->type = FS_DSET_CREATE; - request->data = dset; - request->req = fs_req; - request->next = request->prev = NULL; - /* add request to container's linked list */ - H5VL_iod_request_add(obj->file, request); - /* setup the local dataset struct */ /* store the entire path of the dataset locally */ if (NULL == (dset->common.obj_name = (char *)malloc @@ -1455,12 +1648,52 @@ H5VL_iod_dataset_create(void *_obj, H5VL_loc_params_t loc_params, const char *na if((dset->remote_dset.space_id = H5Scopy(space_id)) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTCOPY, NULL, "failed to copy dspace"); - /* set common object parameters */ dset->common.obj_type = H5I_DATASET; dset->common.file = obj->file; dset->common.file->nopen_objs ++; - dset->common.request = request; + + /* Get async request for operation */ + if(do_async) { + if(NULL == (request = (H5VL_iod_request_t *)H5MM_malloc(sizeof(H5VL_iod_request_t)))) + HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, NULL, "can't allocate IOD VOL request struct"); + } /* end if */ + else + request = &_request; + + /* Set up request */ + HDmemset(request, 0, sizeof(*request)); + request->type = FS_DSET_CREATE; + request->data = dset; + request->req = fs_req; + request->obj = dset; + request->next = request->prev = NULL; + /* add request to container's linked list */ + H5VL_iod_request_add(obj->file, request); + + /* Store/wait on request */ + if(do_async) { + /* Sanity check */ + HDassert(request != &_request); + + /* Set async. request property, for higher layer to retrieve */ + if(H5P_set(plist, H5P_ASYNC_REQ_NAME, &request) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTSET, NULL, "unable to set request") + + /* Track request */ + dset->common.request = request; + } /* end if */ + else { + /* Synchronously wait on the request */ + if(H5VL_iod_request_wait(obj->file, request) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "can't wait on FS request"); + + /* Sanity check */ + HDassert(request == &_request); + + /* Request has completed already */ + dset->common.request = NULL; + } /* end else */ ret_value = (void *)dset; @@ -1490,11 +1723,15 @@ H5VL_iod_dataset_open(void *_obj, H5VL_loc_params_t loc_params, const char *name H5VL_iod_object_t *obj = (H5VL_iod_object_t *)_obj; /* location object to create the dataset */ H5VL_iod_dset_t *dset = NULL; /* the dataset object that is created and passed to the user */ H5VL_iod_dset_open_input_t input; + H5P_genplist_t *plist; iod_obj_id_t iod_id; iod_handle_t iod_oh; char *new_name; - fs_request_t *fs_req; - H5VL_iod_request_t *request; + fs_request_t _fs_req; /* Local function shipper request, for sync. operations */ + fs_request_t *fs_req = NULL; + H5VL_iod_request_t _request; /* Local request, for sync. operations */ + H5VL_iod_request_t *request = NULL; + hbool_t do_async; /* Whether we're performing async. I/O */ void *ret_value = NULL; FUNC_ENTER_NOAPI_NOINIT @@ -1516,24 +1753,26 @@ H5VL_iod_dataset_open(void *_obj, H5VL_loc_params_t loc_params, const char *name input.name = new_name; input.dapl_id = dapl_id; - /* allocate a function shipper request */ - if(NULL == (fs_req = (fs_request_t *)H5MM_malloc(sizeof(fs_request_t)))) - HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, NULL, "can't allocate a FS request"); + /* Get the dapl plist structure */ + if(NULL == (plist = (H5P_genplist_t *)H5I_object(dapl_id))) + HGOTO_ERROR(H5E_DATASET, H5E_BADATOM, NULL, "can't find object for ID") + + /* Get async flag */ + if(H5P_get(plist, H5P_ASYNC_FLAG_NAME, &do_async) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, NULL, "can't get property value for lcpl id"); + + /* get a function shipper request */ + if(do_async) { + if(NULL == (fs_req = (fs_request_t *)H5MM_malloc(sizeof(fs_request_t)))) + HGOTO_ERROR(H5E_DATASET, H5E_NOSPACE, NULL, "can't allocate a FS request"); + } /* end if */ + else + fs_req = &_fs_req; /* forward the call to the IONs */ if(fs_forward(PEER, H5VL_DSET_OPEN_ID, &input, &dset->remote_dset, fs_req) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "failed to ship dataset open"); - /* setup a request to track completion of the operation */ - if(NULL == (request = (H5VL_iod_request_t *)H5MM_malloc(sizeof(H5VL_iod_request_t)))) - HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, NULL, "can't allocate IOD VOL request struct"); - request->type = FS_DSET_OPEN; - request->data = dset; - request->req = fs_req; - request->next = request->prev = NULL; - /* add request to container's linked list */ - H5VL_iod_request_add(obj->file, request); - /* setup the local dataset struct */ /* store the entire path of the dataset locally */ if (NULL == (dset->common.obj_name = (char *)malloc @@ -1550,7 +1789,48 @@ H5VL_iod_dataset_open(void *_obj, H5VL_loc_params_t loc_params, const char *name dset->common.obj_type = H5I_DATASET; dset->common.file = obj->file; dset->common.file->nopen_objs ++; - dset->common.request = request; + + /* Get async request for operation */ + if(do_async) { + if(NULL == (request = (H5VL_iod_request_t *)H5MM_malloc(sizeof(H5VL_iod_request_t)))) + HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, NULL, "can't allocate IOD VOL request struct"); + } /* end if */ + else + request = &_request; + + /* Set up request */ + HDmemset(request, 0, sizeof(*request)); + request->type = FS_DSET_OPEN; + request->data = dset; + request->req = fs_req; + request->obj = dset; + request->next = request->prev = NULL; + /* add request to container's linked list */ + H5VL_iod_request_add(obj->file, request); + + /* Store/wait on request */ + if(do_async) { + /* Sanity check */ + HDassert(request != &_request); + + /* Set async. request property, for higher layer to retrieve */ + if(H5P_set(plist, H5P_ASYNC_REQ_NAME, &request) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTSET, NULL, "unable to set request") + + /* Track request */ + dset->common.request = request; + } /* end if */ + else { + /* Synchronously wait on the request */ + if(H5VL_iod_request_wait(obj->file, request) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "can't wait on FS request"); + + /* Sanity check */ + HDassert(request == &_request); + + /* Request has completed already */ + dset->common.request = NULL; + } /* end else */ ret_value = (void *)dset; @@ -1579,8 +1859,11 @@ H5VL_iod_dataset_read(void *_dset, hid_t mem_type_id, hid_t mem_space_id, { H5VL_iod_dset_t *dset = (H5VL_iod_dset_t *)_dset; H5VL_iod_dset_io_input_t input; + H5P_genplist_t *plist; + fs_request_t _fs_req; /* Local function shipper request, for sync. operations */ fs_request_t *fs_req = NULL; bds_handle_t *bds_handle = NULL; + H5VL_iod_request_t _request; /* Local request, for sync. operations */ H5VL_iod_request_t *request = NULL; H5VL_iod_read_status_t *status = NULL; const H5S_t *mem_space = NULL; @@ -1588,6 +1871,7 @@ H5VL_iod_dataset_read(void *_dset, hid_t mem_type_id, hid_t mem_space_id, char fake_char; size_t size; H5VL_iod_io_info_t *info; + hbool_t do_async; /* Whether we're performing async. I/O */ herr_t ret_value = SUCCEED; FUNC_ENTER_NOAPI_NOINIT @@ -1624,8 +1908,12 @@ H5VL_iod_dataset_read(void *_dset, hid_t mem_type_id, hid_t mem_space_id, if(NULL != dset->common.request) { if(H5VL_iod_request_wait(dset->common.file, dset->common.request) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't wait on FS request"); - dset->common.request->req = H5MM_xfree(dset->common.request->req); - dset->common.request = H5MM_xfree(dset->common.request); + + /* Reset object's pointer to request */ + /* (Request is owned by the request object and will be freed when the + * application calls test or wait on it.) + */ + dset->common.request = NULL; } /* calculate the size of the buffer needed - MSC we are assuming everything is contiguous now */ @@ -1649,9 +1937,21 @@ H5VL_iod_dataset_read(void *_dset, hid_t mem_type_id, hid_t mem_space_id, /* allocate structure to receive status of read operation (contains return value and checksum */ status = (H5VL_iod_read_status_t *)malloc(sizeof(H5VL_iod_read_status_t)); - /* allocate a function shipper request */ - if(NULL == (fs_req = (fs_request_t *)H5MM_malloc(sizeof(fs_request_t)))) - HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, FAIL, "can't allocate a FS request"); + /* Get the dxpl plist structure */ + if(NULL == (plist = (H5P_genplist_t *)H5I_object(dxpl_id))) + HGOTO_ERROR(H5E_DATASET, H5E_BADATOM, FAIL, "can't find object for ID") + + /* Get async flag */ + if(H5P_get(plist, H5P_ASYNC_FLAG_NAME, &do_async) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get property value for lcpl id"); + + /* get a function shipper request */ + if(do_async) { + if(NULL == (fs_req = (fs_request_t *)H5MM_malloc(sizeof(fs_request_t)))) + HGOTO_ERROR(H5E_DATASET, H5E_NOSPACE, FAIL, "can't allocate a FS request"); + } /* end if */ + else + fs_req = &_fs_req; /* forward the call to the IONs */ if(fs_forward(PEER, H5VL_DSET_READ_ID, &input, status, fs_req) < 0) @@ -1665,17 +1965,42 @@ H5VL_iod_dataset_read(void *_dset, hid_t mem_type_id, hid_t mem_space_id, info->bds_handle = bds_handle; info->checksum = write_checksum; - /* setup a request to track completion of the operation */ - if(NULL == (request = (H5VL_iod_request_t *)H5MM_malloc(sizeof(H5VL_iod_request_t)))) - HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, FAIL, "can't allocate IOD VOL request struct"); + /* Get async request for operation */ + if(do_async) { + if(NULL == (request = (H5VL_iod_request_t *)H5MM_malloc(sizeof(H5VL_iod_request_t)))) + HGOTO_ERROR(H5E_DATASET, H5E_NOSPACE, FAIL, "can't allocate IOD VOL request struct"); + } /* end if */ + else + request = &_request; + + /* Set up request */ + HDmemset(request, 0, sizeof(*request)); request->type = FS_DSET_READ; request->data = info; request->req = fs_req; - request->obj_name = HDstrdup(dset->common.obj_name); + request->obj = dset; request->next = request->prev = NULL; /* add request to container's linked list */ H5VL_iod_request_add(dset->common.file, request); + /* Store/wait on request */ + if(do_async) { + /* Sanity check */ + HDassert(request != &_request); + + /* Set async. request property, for higher layer to retrieve */ + if(H5P_set(plist, H5P_ASYNC_REQ_NAME, &request) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "unable to set request") + } /* end if */ + else { + /* Sanity check */ + HDassert(request == &_request); + + /* Synchronously wait on the request */ + if(H5VL_iod_request_wait(dset->common.file, request) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't wait on FS request"); + } /* end else */ + done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5VL_iod_dataset_read() */ @@ -1700,8 +2025,11 @@ H5VL_iod_dataset_write(void *_dset, hid_t mem_type_id, hid_t mem_space_id, { H5VL_iod_dset_t *dset = (H5VL_iod_dset_t *)_dset; H5VL_iod_dset_io_input_t input; + H5P_genplist_t *plist; + fs_request_t _fs_req; /* Local function shipper request, for sync. operations */ fs_request_t *fs_req = NULL; bds_handle_t *bds_handle = NULL; + H5VL_iod_request_t _request; /* Local request, for sync. operations */ H5VL_iod_request_t *request = NULL; const H5S_t *mem_space = NULL; const H5S_t *file_space = NULL; @@ -1710,6 +2038,7 @@ H5VL_iod_dataset_write(void *_dset, hid_t mem_type_id, hid_t mem_space_id, size_t size; H5VL_iod_io_info_t *info; uint32_t cs; + hbool_t do_async; /* Whether we're performing async. I/O */ herr_t ret_value = SUCCEED; FUNC_ENTER_NOAPI_NOINIT @@ -1717,8 +2046,12 @@ H5VL_iod_dataset_write(void *_dset, hid_t mem_type_id, hid_t mem_space_id, if(NULL != dset->common.request) { if(H5VL_iod_request_wait(dset->common.file, dset->common.request) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't wait on FS request"); - dset->common.request->req = H5MM_xfree(dset->common.request->req); - dset->common.request = H5MM_xfree(dset->common.request); + + /* Reset object's pointer to request */ + /* (Request is owned by the request object and will be freed when the + * application calls test or wait on it.) + */ + dset->common.request = NULL; } /* check arguments */ @@ -1776,9 +2109,21 @@ H5VL_iod_dataset_write(void *_dset, hid_t mem_type_id, hid_t mem_space_id, status = (int *)malloc(sizeof(int)); - /* allocate a function shipper request */ - if(NULL == (fs_req = (fs_request_t *)H5MM_malloc(sizeof(fs_request_t)))) - HGOTO_ERROR(H5E_DATASET, H5E_NOSPACE, FAIL, "can't allocate a FS request"); + /* Get the dxpl plist structure */ + if(NULL == (plist = (H5P_genplist_t *)H5I_object(dxpl_id))) + HGOTO_ERROR(H5E_DATASET, H5E_BADATOM, FAIL, "can't find object for ID") + + /* Get async flag */ + if(H5P_get(plist, H5P_ASYNC_FLAG_NAME, &do_async) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get property value for lcpl id"); + + /* get a function shipper request */ + if(do_async) { + if(NULL == (fs_req = (fs_request_t *)H5MM_malloc(sizeof(fs_request_t)))) + HGOTO_ERROR(H5E_DATASET, H5E_NOSPACE, FAIL, "can't allocate a FS request"); + } /* end if */ + else + fs_req = &_fs_req; /* forward the call to the IONs */ if(fs_forward(PEER, H5VL_DSET_WRITE_ID, &input, status, fs_req) < 0) @@ -1792,17 +2137,42 @@ H5VL_iod_dataset_write(void *_dset, hid_t mem_type_id, hid_t mem_space_id, info->bds_handle = bds_handle; info->checksum = cs; - /* setup a request to track completion of the operation */ - if(NULL == (request = (H5VL_iod_request_t *)H5MM_malloc(sizeof(H5VL_iod_request_t)))) - HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, FAIL, "can't allocate IOD VOL request struct"); + /* Get async request for operation */ + if(do_async) { + if(NULL == (request = (H5VL_iod_request_t *)H5MM_malloc(sizeof(H5VL_iod_request_t)))) + HGOTO_ERROR(H5E_DATASET, H5E_NOSPACE, FAIL, "can't allocate IOD VOL request struct"); + } /* end if */ + else + request = &_request; + + /* Set up request */ + HDmemset(request, 0, sizeof(*request)); request->type = FS_DSET_WRITE; request->data = info; request->req = fs_req; - request->obj_name = HDstrdup(dset->common.obj_name); + request->obj = dset; request->next = request->prev = NULL; /* add request to container's linked list */ H5VL_iod_request_add(dset->common.file, request); + /* Store/wait on request */ + if(do_async) { + /* Sanity check */ + HDassert(request != &_request); + + /* Set async. request property, for higher layer to retrieve */ + if(H5P_set(plist, H5P_ASYNC_REQ_NAME, &request) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "unable to set request") + } /* end if */ + else { + /* Sanity check */ + HDassert(request == &_request); + + /* Synchronously wait on the request */ + if(H5VL_iod_request_wait(dset->common.file, request) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't wait on FS request"); + } /* end else */ + done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5VL_iod_dataset_write() */ @@ -1828,8 +2198,10 @@ H5VL_iod_dataset_set_extent(void *_dset, const hsize_t size[], hid_t UNUSED req) H5VL_iod_dset_set_extent_input_t input; iod_obj_id_t iod_id; iod_handle_t iod_oh; - fs_request_t *fs_req; - H5VL_iod_request_t *request; + fs_request_t _fs_req; /* Local function shipper request, for sync. operations */ + fs_request_t *fs_req = &_fs_req; + H5VL_iod_request_t _request; /* Local request, for sync. operations */ + H5VL_iod_request_t *request = &_request; int *status = NULL; herr_t ret_value = SUCCEED; /* Return value */ @@ -1839,12 +2211,16 @@ H5VL_iod_dataset_set_extent(void *_dset, const hsize_t size[], hid_t UNUSED req) if(NULL != dset->common.request) { if(H5VL_iod_request_wait(dset->common.file, dset->common.request) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't wait on FS request"); - dset->common.request->req = H5MM_xfree(dset->common.request->req); - dset->common.request = H5MM_xfree(dset->common.request); + + /* Reset object's pointer to request */ + /* (Request is owned by the request object and will be freed when the + * application calls test or wait on it.) + */ + dset->common.request = NULL; } /* wait for pending I/O requests on the dataset */ - if(H5VL_iod_request_wait_some(dset->common.file, dset->common.obj_name) < 0) + if(H5VL_iod_request_wait_some(dset->common.file, dset) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't wait on FS requests"); /* Fill input structure */ @@ -1854,26 +2230,26 @@ H5VL_iod_dataset_set_extent(void *_dset, const hsize_t size[], hid_t UNUSED req) status = (int *)malloc(sizeof(int)); - /* allocate a function shipper request */ - if(NULL == (fs_req = (fs_request_t *)H5MM_malloc(sizeof(fs_request_t)))) - HGOTO_ERROR(H5E_DATASET, H5E_NOSPACE, FAIL, "can't allocate a FS request"); - /* forward the call to the IONs */ if(fs_forward(PEER, H5VL_DSET_SET_EXTENT_ID, &input, status, fs_req) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "failed to ship dataset write"); - /* setup a request to track completion of the operation */ - if(NULL == (request = (H5VL_iod_request_t *)H5MM_malloc(sizeof(H5VL_iod_request_t)))) - HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, FAIL, "can't allocate IOD VOL request struct"); + /* Set up request */ + HDmemset(request, 0, sizeof(*request)); request->type = FS_DSET_SET_EXTENT; request->data = status; request->req = fs_req; + request->obj = dset; request->next = request->prev = NULL; /* add request to container's linked list */ H5VL_iod_request_add(dset->common.file, request); - /* set this request to be the creation request pending for this dataset now */ - dset->common.request = request; + /* Synchronously wait on the request (no way to return request object currently) */ + if(H5VL_iod_request_wait(dset->common.file, request) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't wait on FS request"); + if(SUCCEED != *status) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCLOSEOBJ, FAIL, "dataset close failed at the server") + free(status); done: FUNC_LEAVE_NOAPI(ret_value) @@ -1971,9 +2347,11 @@ static herr_t H5VL_iod_dataset_close(void *_dset, hid_t UNUSED req) { H5VL_iod_dset_t *dset = (H5VL_iod_dset_t *)_dset; - fs_request_t *fs_req; + fs_request_t _fs_req; /* Local function shipper request, for sync. operations */ + fs_request_t *fs_req = &_fs_req; int *status; - H5VL_iod_request_t *request; + H5VL_iod_request_t _request; /* Local request, for sync. operations */ + H5VL_iod_request_t *request = &_request; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT @@ -1981,31 +2359,40 @@ H5VL_iod_dataset_close(void *_dset, hid_t UNUSED req) if(NULL != dset->common.request) { if(H5VL_iod_request_wait(dset->common.file, dset->common.request) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't wait on FS request"); - dset->common.request->req = H5MM_xfree(dset->common.request->req); - dset->common.request = H5MM_xfree(dset->common.request); + + /* Reset object's pointer to request */ + /* (Request is owned by the request object and will be freed when the + * application calls test or wait on it.) + */ + dset->common.request = NULL; } - if(H5VL_iod_request_wait_some(dset->common.file, dset->common.obj_name) < 0) + if(H5VL_iod_request_wait_some(dset->common.file, dset) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't wait on FS requests"); - if(NULL == (fs_req = (fs_request_t *)H5MM_malloc(sizeof(fs_request_t)))) - HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, FAIL, "can't allocate a FS request"); - status = (int *)malloc(sizeof(int)); + /* forward the call to the IONs */ if(fs_forward(PEER, H5VL_DSET_CLOSE_ID, &dset->remote_dset, status, fs_req) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "failed to ship dset close"); - /* setup a request to track completion of the operation */ - if(NULL == (request = (H5VL_iod_request_t *)H5MM_malloc(sizeof(H5VL_iod_request_t)))) - HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, FAIL, "can't allocate IOD VOL request struct"); + /* Set up request */ + HDmemset(request, 0, sizeof(*request)); request->type = FS_DSET_CLOSE; request->data = status; request->req = fs_req; + request->obj = dset; request->next = request->prev = NULL; /* add request to container's linked list */ H5VL_iod_request_add(dset->common.file, request); + /* Synchronously wait on the request (no way to return request object currently) */ + if(H5VL_iod_request_wait(dset->common.file, request) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't wait on FS request"); + if(SUCCEED != *status) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCLOSEOBJ, FAIL, "dataset close failed at the server") + free(status); + free(dset->common.obj_name); if(H5Pclose(dset->remote_dset.dcpl_id) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "failed to close plist"); diff --git a/src/H5VLiod_client.c b/src/H5VLiod_client.c index 29abe84..50ea973 100644 --- a/src/H5VLiod_client.c +++ b/src/H5VLiod_client.c @@ -89,6 +89,7 @@ H5VL_iod_request_delete(H5VL_iod_file_t *file, H5VL_iod_request_t *request) } } + request->obj->request = NULL; request->prev = NULL; request->next = NULL; @@ -99,6 +100,7 @@ herr_t H5VL_iod_request_wait(H5VL_iod_file_t *file, H5VL_iod_request_t *request) { H5VL_iod_request_t *cur_req = file->request_list_head; + int ret; fs_status_t status; FUNC_ENTER_NOAPI_NOINIT_NOERR @@ -109,9 +111,21 @@ H5VL_iod_request_wait(H5VL_iod_file_t *file, H5VL_iod_request_t *request) /* Loop to complete the request while poking through other requests on the container to avoid deadlock. */ while(1) { + //fs_wait(*((fs_request_t *)request->req), FS_MAX_IDLE_TIME, &status); /* test the operation status */ - fs_wait(*((fs_request_t *)request->req), 0, &status); - + ret = fs_wait(*((fs_request_t *)request->req), 0, &status); + if(S_FAIL == ret) { + request->status = H5AO_FAILED; + request->state = H5VL_IOD_COMPLETED; + H5VL_iod_request_delete(file, request); + break; + } + else { + if(status) { + request->status = H5AO_SUCCEEDED; + request->state = H5VL_IOD_COMPLETED; + } + } /* if it has not completed, go through the list of requests on the container to test progress */ if(!status) { @@ -121,13 +135,19 @@ H5VL_iod_request_wait(H5VL_iod_file_t *file, H5VL_iod_request_t *request) fs_status_t tmp_status; tmp_req = cur_req->next; - fs_wait(*((fs_request_t *)cur_req->req), 0, &tmp_status); - if(tmp_status) { + ret = fs_wait(*((fs_request_t *)cur_req->req), 0, &tmp_status); + if(S_FAIL == ret) { + cur_req->status = H5AO_FAILED; + cur_req->state = H5VL_IOD_COMPLETED; H5VL_iod_request_delete(file, cur_req); - cur_req->req = H5MM_xfree(cur_req->req); - cur_req = H5MM_xfree(cur_req); } - + else { + if(tmp_status) { + cur_req->status = H5AO_SUCCEEDED; + cur_req->state = H5VL_IOD_COMPLETED; + H5VL_iod_request_delete(file, cur_req); + } + } /* next time, test the next request in the list */ cur_req = tmp_req; } @@ -138,7 +158,6 @@ H5VL_iod_request_wait(H5VL_iod_file_t *file, H5VL_iod_request_t *request) break; } } - FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5VL_iod_wait */ @@ -147,6 +166,7 @@ H5VL_iod_request_wait_all(H5VL_iod_file_t *file) { H5VL_iod_request_t *cur_req = file->request_list_head; fs_status_t status; + int ret; herr_t ret_value = SUCCEED; FUNC_ENTER_NOAPI_NOINIT @@ -156,9 +176,16 @@ H5VL_iod_request_wait_all(H5VL_iod_file_t *file) H5VL_iod_request_t *tmp_req = NULL; tmp_req = cur_req->next; - fs_wait(*((fs_request_t *)cur_req->req), FS_MAX_IDLE_TIME, &status); - if(!status) - HGOTO_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "a pending request did not complete"); + ret = fs_wait(*((fs_request_t *)cur_req->req), FS_MAX_IDLE_TIME, &status); + if(S_FAIL == ret) { + cur_req->status = H5AO_FAILED; + cur_req->state = H5VL_IOD_COMPLETED; + } + else { + HDassert(status); + cur_req->status = H5AO_SUCCEEDED; + cur_req->state = H5VL_IOD_COMPLETED; + } if(FS_DSET_WRITE == cur_req->type || FS_DSET_READ == cur_req->type) { H5VL_iod_io_info_t *info = (H5VL_iod_io_info_t *)cur_req->data; @@ -170,38 +197,34 @@ H5VL_iod_request_wait_all(H5VL_iod_file_t *file) if(FS_DSET_WRITE == cur_req->type && SUCCEED != *((int *)info->status)) HGOTO_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "Dataset I/O failed") else if(FS_DSET_READ == cur_req->type) { - H5VL_iod_read_status_t *status = (H5VL_iod_read_status_t *)info->status; + H5VL_iod_read_status_t *read_status = (H5VL_iod_read_status_t *)info->status; - if(SUCCEED != status->ret) { + if(SUCCEED != read_status->ret) { free(info->status); info->status = NULL; - info->bds_handle = H5MM_xfree(info->bds_handle); - HDfree(cur_req->obj_name); - info = H5MM_xfree(info); + info->bds_handle = (bds_handle_t *)H5MM_xfree(info->bds_handle); + info = (H5VL_iod_io_info_t *)H5MM_xfree(info); HGOTO_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "Dataset I/O failed"); } - if(info->checksum && info->checksum != status->cs) { + if(info->checksum && info->checksum != read_status->cs) { //free(info->status); //info->status = NULL; - //info->bds_handle = H5MM_xfree(info->bds_handle); + //info->bds_handle = (bds_handle_t *)H5MM_xfree(info->bds_handle); //HDfree(cur_req->obj_name); - //info = H5MM_xfree(info); + //info = (H5VL_iod_io_info_t *)H5MM_xfree(info); /* MSC not returning an error because we injected this failure */ fprintf(stderr, "Fatal Error! Data integrity failure (expecting %u got %u).\n", - info->checksum, status->cs); + info->checksum, read_status->cs); //HGOTO_ERROR(H5E_SYM, H5E_CANTFREE, SUCCEED, "Data Integrity Fail - bad Checksum"); } } free(info->status); info->status = NULL; - info->bds_handle = H5MM_xfree(info->bds_handle); - info = H5MM_xfree(info); - HDfree(cur_req->obj_name); + info->bds_handle = (bds_handle_t *)H5MM_xfree(info->bds_handle); + info = (H5VL_iod_io_info_t *)H5MM_xfree(info); } H5VL_iod_request_delete(file, cur_req); - cur_req->req = H5MM_xfree(cur_req->req); - cur_req = H5MM_xfree(cur_req); cur_req = tmp_req; } @@ -210,10 +233,11 @@ done: } /* end H5VL_iod_request_wait_all */ herr_t -H5VL_iod_request_wait_some(H5VL_iod_file_t *file, const char *name) +H5VL_iod_request_wait_some(H5VL_iod_file_t *file, const void *object) { H5VL_iod_request_t *cur_req = file->request_list_head; fs_status_t status; + int ret; herr_t ret_value = SUCCEED; FUNC_ENTER_NOAPI_NOINIT @@ -227,10 +251,18 @@ H5VL_iod_request_wait_some(H5VL_iod_file_t *file, const char *name) if(FS_DSET_WRITE == cur_req->type || FS_DSET_READ == cur_req->type) { H5VL_iod_io_info_t *info = (H5VL_iod_io_info_t *)cur_req->data; - if(!HDstrcmp(name, cur_req->obj_name)) { - fs_wait(*((fs_request_t *)cur_req->req), FS_MAX_IDLE_TIME, &status); - if(!status) - HGOTO_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "a pending request did not complete"); + if(cur_req->obj == object) { + ret = fs_wait(*((fs_request_t *)cur_req->req), FS_MAX_IDLE_TIME, + &status); + if(S_FAIL == ret) { + cur_req->status = H5AO_FAILED; + cur_req->state = H5VL_IOD_COMPLETED; + } + else { + HDassert(status); + cur_req->status = H5AO_SUCCEEDED; + cur_req->state = H5VL_IOD_COMPLETED; + } /* Free memory handle */ if(S_SUCCESS != bds_handle_free(*info->bds_handle)) @@ -239,38 +271,36 @@ H5VL_iod_request_wait_some(H5VL_iod_file_t *file, const char *name) if(FS_DSET_WRITE == cur_req->type && SUCCEED != *((int *)info->status)) HGOTO_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "Dataset I/O failed") else if(FS_DSET_READ == cur_req->type) { - H5VL_iod_read_status_t *status = (H5VL_iod_read_status_t *)info->status; + H5VL_iod_read_status_t *read_status = (H5VL_iod_read_status_t *)info->status; - if(SUCCEED != status->ret) { + if(SUCCEED != read_status->ret) { free(info->status); info->status = NULL; - info->bds_handle = H5MM_xfree(info->bds_handle); - HDfree(cur_req->obj_name); - info = H5MM_xfree(info); + info->bds_handle = (bds_handle_t *)H5MM_xfree(info->bds_handle); + info = (H5VL_iod_io_info_t *)H5MM_xfree(info); HGOTO_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "Dataset I/O failed"); } - if(info->checksum && info->checksum != status->cs) { + if(info->checksum && info->checksum != read_status->cs) { //free(info->status); //info->status = NULL; - //info->bds_handle = H5MM_xfree(info->bds_handle); + //info->bds_handle = (bds_handle_t *)H5MM_xfree(info->bds_handle); //HDfree(cur_req->obj_name); - //info = H5MM_xfree(info); + //info = (H5VL_iod_io_info_t *)H5MM_xfree(info); /* MSC not returning an error because we injected this failure */ fprintf(stderr, "Fatal Error! Data integrity failure (expecting %u got %u).\n", - info->checksum, status->cs); + info->checksum, read_status->cs); //HGOTO_ERROR(H5E_SYM, H5E_CANTFREE, SUCCEED, "Data Integrity Fail - bad Checksum"); } } free(info->status); info->status = NULL; - info->bds_handle = H5MM_xfree(info->bds_handle); - HDfree(cur_req->obj_name); - info = H5MM_xfree(info); + info->bds_handle = (bds_handle_t *)H5MM_xfree(info->bds_handle); + info = (H5VL_iod_io_info_t *)H5MM_xfree(info); H5VL_iod_request_delete(file, cur_req); - cur_req->req = H5MM_xfree(cur_req->req); - cur_req = H5MM_xfree(cur_req); + + /* QAK: NULL object's request pointer? */ } } cur_req = tmp_req; @@ -306,8 +336,12 @@ H5VL_iod_local_traverse(H5VL_iod_object_t *obj, H5VL_loc_params_t UNUSED loc_par if(NULL != obj->request) { if(H5VL_iod_request_wait(obj->file, obj->request) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't wait on FS request"); - obj->request->req = H5MM_xfree(obj->request->req); - obj->request = H5MM_xfree(obj->request); + + /* Reset object's pointer to request */ + /* (Request is owned by the request object and will be freed when the + * application calls test or wait on it.) + */ + obj->request = NULL; } if(H5I_FILE == obj->obj_type) { @@ -364,8 +398,11 @@ H5VL_iod_local_traverse(H5VL_iod_object_t *obj, H5VL_loc_params_t UNUSED loc_par if(H5VL_iod_request_wait(obj->file, cur_grp->common.request) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't wait on FS request"); - cur_grp->common.request->req = H5MM_xfree(cur_grp->common.request->req); - cur_grp->common.request = H5MM_xfree(cur_grp->common.request); + /* Reset object's pointer to request */ + /* (Request is owned by the request object and will be freed when the + * application calls test or wait on it.) + */ + cur_grp->common.request = NULL; } cur_id = cur_grp->remote_group.iod_id; @@ -438,7 +475,6 @@ H5VL_iod_client_eff_finalize(na_addr_t ion_target) if (fs_ret != S_SUCCESS) HGOTO_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "failed to finalize function shipper"); - H5_term_library(); done: FUNC_LEAVE_NOAPI(ret_value) } diff --git a/src/H5VLiod_client.h b/src/H5VLiod_client.h index 08e0a10..4fd8235 100644 --- a/src/H5VLiod_client.h +++ b/src/H5VLiod_client.h @@ -19,11 +19,13 @@ #ifndef _H5VLiod_client_H #define _H5VLiod_client_H +#include "H5FFprivate.h" /* FastForward wrappers */ #include "H5VLiod.h" /* Iod VOL plugin */ #include "H5VLiod_common.h" /* forward declaration of file struct */ struct H5VL_iod_file_t; +struct H5VL_iod_object_t; /* types for requests */ typedef enum H5RQ_type_t { @@ -42,12 +44,19 @@ typedef enum H5RQ_type_t { FS_DSET_CLOSE } H5RQ_type_t; +typedef enum H5VL_iod_state_t { + H5VL_IOD_PENDING, + H5VL_IOD_COMPLETED +} H5VL_iod_state_t; + /* the client IOD VOL request struct */ typedef struct H5VL_iod_request_t { H5RQ_type_t type; void *data; void *req; - char *obj_name; + struct H5VL_iod_object_t *obj; + H5VL_iod_state_t state; + H5_status_t status; struct H5VL_iod_request_t *prev; struct H5VL_iod_request_t *next; } H5VL_iod_request_t; @@ -97,7 +106,7 @@ H5_DLL herr_t H5VL_iod_request_delete(H5VL_iod_file_t *file, H5VL_iod_request_t H5_DLL herr_t H5VL_iod_request_add(H5VL_iod_file_t *file, H5VL_iod_request_t *request); H5_DLL herr_t H5VL_iod_request_wait(H5VL_iod_file_t *file, H5VL_iod_request_t *request); H5_DLL herr_t H5VL_iod_request_wait_all(H5VL_iod_file_t *file); -H5_DLL herr_t H5VL_iod_request_wait_some(H5VL_iod_file_t *file, const char *name); +H5_DLL herr_t H5VL_iod_request_wait_some(H5VL_iod_file_t *file, const void *object); H5_DLL herr_t H5VL_iod_local_traverse(H5VL_iod_object_t *obj, H5VL_loc_params_t loc_params, const char *name, iod_obj_id_t *id, iod_handle_t *oh, char **new_name); diff --git a/src/H5VLiod_server.c b/src/H5VLiod_server.c index 54bbf8c..0a2f847 100644 --- a/src/H5VLiod_server.c +++ b/src/H5VLiod_server.c @@ -922,10 +922,10 @@ done: if(ret_value < 0) fs_handler_complete(input->fs_handle, &ret_value); - if(H5P_FILE_CREATE_DEFAULT != input->fcpl_id) - H5Pclose(input->fcpl_id); - if(H5P_FILE_ACCESS_DEFAULT != input->fapl_id) - H5Pclose(input->fapl_id); + //if(H5P_FILE_CREATE_DEFAULT != input->fcpl_id) + //H5Pclose(input->fcpl_id); + //if(H5P_FILE_ACCESS_DEFAULT != input->fapl_id) + //H5Pclose(input->fapl_id); H5MM_free(input->name); input = H5MM_xfree(input); FUNC_LEAVE_NOAPI(ret_value) @@ -992,8 +992,8 @@ done: if(ret_value < 0) fs_handler_complete(input->fs_handle, &ret_value); - if(H5P_FILE_ACCESS_DEFAULT != input->fapl_id) - H5Pclose(input->fapl_id); + //if(H5P_FILE_ACCESS_DEFAULT != input->fapl_id) + //H5Pclose(input->fapl_id); H5MM_free(input->name); input = H5MM_xfree(input); @@ -1232,12 +1232,12 @@ done: if(ret_value < 0) fs_handler_complete(input->fs_handle, &ret_value); - if(H5P_GROUP_CREATE_DEFAULT != input->gcpl_id) - H5Pclose(input->gcpl_id); - if(H5P_GROUP_ACCESS_DEFAULT != input->gapl_id) - H5Pclose(input->gapl_id); - if(H5P_LINK_CREATE_DEFAULT != input->lcpl_id) - H5Pclose(input->lcpl_id); + //if(H5P_GROUP_CREATE_DEFAULT != input->gcpl_id) + //H5Pclose(input->gcpl_id); + //if(H5P_GROUP_ACCESS_DEFAULT != input->gapl_id) + //H5Pclose(input->gapl_id); + //if(H5P_LINK_CREATE_DEFAULT != input->lcpl_id) + //H5Pclose(input->lcpl_id); H5MM_free(input->name); input = H5MM_xfree(input); FUNC_LEAVE_NOAPI(ret_value) @@ -1367,8 +1367,8 @@ done: H5MM_xfree(output.gcpl); - if(H5P_GROUP_ACCESS_DEFAULT != input->gapl_id) - H5Pclose(input->gapl_id); + //if(H5P_GROUP_ACCESS_DEFAULT != input->gapl_id) + //H5Pclose(input->gapl_id); H5MM_free(input->name); input = H5MM_xfree(input); @@ -1609,8 +1609,8 @@ H5VL_iod_server_dset_create_cb(size_t UNUSED num_necessary_parents, AXE_task_t U HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't set KV pair in parent"); HDfree(kv.key); free(kv.value); - if(H5P_DATASET_CREATE_DEFAULT != input->dcpl_id) - H5Pclose(input->dcpl_id); + //if(H5P_DATASET_CREATE_DEFAULT != input->dcpl_id) + //H5Pclose(input->dcpl_id); /* insert datatyoe metadata into scratch pad */ kv.key = HDstrdup("dataset_dtype"); @@ -1666,11 +1666,12 @@ done: if(ret_value < 0) fs_handler_complete(input->fs_handle, &ret_value); - if(H5P_DATASET_ACCESS_DEFAULT != input->dapl_id) - H5Pclose(input->dapl_id); - if(H5P_LINK_CREATE_DEFAULT != input->lcpl_id) - H5Pclose(input->lcpl_id); + //if(H5P_DATASET_ACCESS_DEFAULT != input->dapl_id) + //H5Pclose(input->dapl_id); + //if(H5P_LINK_CREATE_DEFAULT != input->lcpl_id) + //H5Pclose(input->lcpl_id); H5MM_free(input->name); + input = H5MM_xfree(input); FUNC_LEAVE_NOAPI(ret_value) } /* end H5VL_iod_server_dset_create_cb() */ @@ -1817,8 +1818,8 @@ done: H5MM_xfree(output.dtype); H5MM_xfree(output.dspace); - if(H5P_DATASET_ACCESS_DEFAULT != input->dapl_id) - H5Pclose(input->dapl_id); + //if(H5P_DATASET_ACCESS_DEFAULT != input->dapl_id) + //H5Pclose(input->dapl_id); H5MM_free(input->name); input = H5MM_xfree(input); @@ -1918,8 +1919,8 @@ done: if(S_SUCCESS != bds_block_handle_free(bds_block_handle)) HDONE_ERROR(H5E_SYM, H5E_WRITEERROR, FAIL, "can't free bds block handle"); - if(H5P_DATASET_XFER_DEFAULT != input->dxpl_id) - H5Pclose(input->dxpl_id); + //if(H5P_DATASET_XFER_DEFAULT != input->dxpl_id) + //H5Pclose(input->dxpl_id); H5Sclose(input->space_id); input = H5MM_xfree(input); @@ -2010,8 +2011,8 @@ done: //if(S_SUCCESS != bds_block_handle_free(bds_block_handle)) //HDONE_ERROR(H5E_SYM, H5E_WRITEERROR, FAIL, "can't free bds block handle"); - if(H5P_DATASET_XFER_DEFAULT != input->dxpl_id) - H5Pclose(input->dxpl_id); + //if(H5P_DATASET_XFER_DEFAULT != input->dxpl_id) + //H5Pclose(input->dxpl_id); H5Sclose(input->space_id); input = H5MM_xfree(input); diff --git a/src/Makefile.am b/src/Makefile.am index 2394a34..0ef5bac 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -64,6 +64,7 @@ libhdf5_la_SOURCES= H5.c H5checksum.c H5dbg.c H5system.c H5timer.c H5trace.c \ H5FD.c H5FDcore.c \ H5FDdirect.c H5FDfamily.c H5FDint.c H5FDlog.c H5FDmpi.c H5FDmpio.c \ H5FDmpiposix.c H5FDmulti.c H5FDsec2.c H5FDspace.c H5FDstdio.c \ + H5FF.c \ H5FL.c H5FO.c H5FS.c H5FScache.c H5FSdbg.c H5FSsection.c H5FSstat.c H5FStest.c \ H5G.c H5Gbtree2.c H5Gcache.c \ H5Gcompact.c H5Gdense.c H5Gdeprec.c H5Gent.c \ diff --git a/src/Makefile.in b/src/Makefile.in index 6db3da0..cc973a0 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -141,7 +141,7 @@ am_libhdf5_la_OBJECTS = H5.lo H5checksum.lo H5dbg.lo H5system.lo \ H5VLiod_server_encdec.lo H5FD.lo H5FDcore.lo H5FDdirect.lo \ H5FDfamily.lo H5FDint.lo H5FDlog.lo H5FDmpi.lo H5FDmpio.lo \ H5FDmpiposix.lo H5FDmulti.lo H5FDsec2.lo H5FDspace.lo \ - H5FDstdio.lo H5FL.lo H5FO.lo H5FS.lo H5FScache.lo H5FSdbg.lo \ + H5FDstdio.lo H5FF.lo H5FL.lo H5FO.lo H5FS.lo H5FScache.lo H5FSdbg.lo \ H5FSsection.lo H5FSstat.lo H5FStest.lo H5G.lo H5Gbtree2.lo \ H5Gcache.lo H5Gcompact.lo H5Gdense.lo H5Gdeprec.lo H5Gent.lo \ H5Gint.lo H5Glink.lo H5Gloc.lo H5Gname.lo H5Gnode.lo H5Gobj.lo \ @@ -555,6 +555,7 @@ libhdf5_la_SOURCES = H5.c H5checksum.c H5dbg.c H5system.c H5timer.c H5trace.c \ H5FD.c H5FDcore.c \ H5FDdirect.c H5FDfamily.c H5FDint.c H5FDlog.c H5FDmpi.c H5FDmpio.c \ H5FDmpiposix.c H5FDmulti.c H5FDsec2.c H5FDspace.c H5FDstdio.c \ + H5FF.c \ H5FL.c H5FO.c H5FS.c H5FScache.c H5FSdbg.c H5FSsection.c H5FSstat.c H5FStest.c \ H5G.c H5Gbtree2.c H5Gcache.c \ H5Gcompact.c H5Gdense.c H5Gdeprec.c H5Gent.c \ @@ -822,6 +823,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5FDsec2.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5FDspace.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5FDstdio.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5FF.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5FL.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5FO.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5FS.Plo@am__quote@ diff --git a/src/hdf5.h b/src/hdf5.h index 4e2cddd..2254adf 100644 --- a/src/hdf5.h +++ b/src/hdf5.h @@ -28,6 +28,7 @@ #include "H5Epublic.h" /* Errors */ #include "H5Fpublic.h" /* Files */ #include "H5FDpublic.h" /* File drivers */ +#include "H5FFpublic.h" /* FastForward wrappers */ #include "H5Gpublic.h" /* Groups */ #include "H5Ipublic.h" /* ID management */ #include "H5Lpublic.h" /* Links */ diff --git a/testpar/test_client.c b/testpar/test_client.c index 4ab964f..01460a6 100644 --- a/testpar/test_client.c +++ b/testpar/test_client.c @@ -19,6 +19,8 @@ int main(int argc, char **argv) { hsize_t dims[1]; int my_rank, my_size; int provided; + H5_request_t req1, req2, req3, req4, req5, req6, req7, req8; + H5_status_t status1, status2, status3, status4, status5, status6, status7, status8; MPI_Init_thread(&argc, &argv, MPI_THREAD_MULTIPLE, &provided); if(MPI_THREAD_MULTIPLE != provided) { @@ -64,7 +66,11 @@ int main(int argc, char **argv) { HDF5 API routine, so no request is returned. However waiting on requests is built in the IOD VOL plugin for now (explained as we proceed). */ - file_id = H5Fcreate(file_name, H5F_ACC_TRUNC, H5P_DEFAULT, fapl_id); + //file_id = H5Fcreate(file_name, H5F_ACC_TRUNC, H5P_DEFAULT, fapl_id); + file_id = H5Fcreate_ff(file_name, H5F_ACC_TRUNC, H5P_DEFAULT, fapl_id, &req1); + + assert(H5AOwait(&req1, &status1) == 0); + assert (status1); /* create a dataspace. This is a local Bookeeping operation that does not touch the file */ @@ -76,6 +82,7 @@ int main(int argc, char **argv) { complete at the client, then forwards the call asynchronously to the server. */ gid1 = H5Gcreate2(file_id, "G1", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + //gid1 = H5Gcreate_ff(file_id, "G1", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT, 0, &req2); assert(gid1); /* create a Dataset D1 on the file, but in group /G1/G2/G3. This is asynchronous. @@ -85,40 +92,57 @@ int main(int argc, char **argv) { This enforces a wait for the previous H5Gcreate on G1 to complete at the client, then forwards the call asynchronously to the server, with the path G2/G3/D1 */ - did1 = H5Dcreate(file_id,"G1/G2/G3/D1",H5T_NATIVE_INT,dataspaceId, - H5P_DEFAULT,H5P_DEFAULT,H5P_DEFAULT); + //did1 = H5Dcreate(file_id,"G1/G2/G3/D1",H5T_NATIVE_INT,dataspaceId, + //H5P_DEFAULT,H5P_DEFAULT,H5P_DEFAULT); + did1 = H5Dcreate_ff(file_id,"G1/G2/G3/D1",H5T_NATIVE_INT,dataspaceId, + H5P_DEFAULT,H5P_DEFAULT,H5P_DEFAULT, 0, &req3); assert(did1); /* similar to the previous H5Dcreate. As soon as G1 is created, this can execute asynchronously and concurrently with the H5Dcreate for D1 (i.e. no dependency)*/ - did2 = H5Dcreate(file_id,"G1/G2/G3/D2",H5T_NATIVE_INT,dataspaceId, - H5P_DEFAULT,H5P_DEFAULT,H5P_DEFAULT); + //did2 = H5Dcreate(file_id,"G1/G2/G3/D2",H5T_NATIVE_INT,dataspaceId, + //H5P_DEFAULT,H5P_DEFAULT,H5P_DEFAULT); + did2 = H5Dcreate_ff(file_id,"G1/G2/G3/D2",H5T_NATIVE_INT,dataspaceId, + H5P_DEFAULT,H5P_DEFAULT,H5P_DEFAULT, 0, &req4); assert(did2); /* similar to the previous H5Dcreate. As soon as G1 is created, this can execute asynchronously and concurrently with the H5Dcreate for D1 and D2 (i.e. no dependency)*/ - did3 = H5Dcreate(file_id,"G1/G2/G3/D3",H5T_NATIVE_INT,dataspaceId, - H5P_DEFAULT,H5P_DEFAULT,H5P_DEFAULT); + //did3 = H5Dcreate(file_id,"G1/G2/G3/D3",H5T_NATIVE_INT,dataspaceId, + //H5P_DEFAULT,H5P_DEFAULT,H5P_DEFAULT); + did3 = H5Dcreate_ff(file_id,"G1/G2/G3/D3",H5T_NATIVE_INT,dataspaceId, + H5P_DEFAULT,H5P_DEFAULT,H5P_DEFAULT, 0, &req5); assert(did3); - /* NOTE: all raw data reads/writes execute concurrently at the server if they get scheduled by the AXE (i.e. no dependencies on each other). */ /* Raw data write on D1. This is asynchronous, but it is delayed internally at the client until the create for D1 is completed. Internally we generate a checksum for data and ship it with the write call to the server. */ - H5Dwrite(did1, H5T_NATIVE_INT, dataspaceId, dataspaceId, H5P_DEFAULT, data); + //H5Dwrite(did1, H5T_NATIVE_INT, dataspaceId, dataspaceId, H5P_DEFAULT, data); + H5Dwrite_ff(did1, H5T_NATIVE_INT, dataspaceId, dataspaceId, H5P_DEFAULT, data, 0, &req6); /* Raw data write on D2. This is asynchronous, but it is delayed internally at the client until the create for D2 is completed. Internally we generate a checksum for data2 and ship it with the write call to the server.*/ - H5Dwrite(did2, H5T_NATIVE_INT, dataspaceId, dataspaceId, H5P_DEFAULT, data2); + //H5Dwrite(did2, H5T_NATIVE_INT, dataspaceId, dataspaceId, H5P_DEFAULT, data2); + H5Dwrite_ff(did2, H5T_NATIVE_INT, dataspaceId, dataspaceId, H5P_DEFAULT, data2, 0, &req7); /* Raw data write on D3. This is asynchronous, but it is delayed internally at the client until the create for D3 is completed. Internally we generate a checksum for data3 and ship it with the write call to the server.*/ - H5Dwrite(did3, H5T_NATIVE_INT, dataspaceId, dataspaceId, H5P_DEFAULT, data3); + //H5Dwrite(did3, H5T_NATIVE_INT, dataspaceId, dataspaceId, H5P_DEFAULT, data3); + H5Dwrite_ff(did3, H5T_NATIVE_INT, dataspaceId, dataspaceId, H5P_DEFAULT, data3, 0, &req8); + + //assert(H5AOwait(&req2, &status2) == 0); + //assert (status2); + assert(H5AOwait(&req3, &status3) == 0); + assert (status3); + assert(H5AOwait(&req4, &status4) == 0); + assert (status4); + assert(H5AOwait(&req5, &status5) == 0); + assert (status5); /* Raw data read on D1. This is asynchronous, but it is delayed internally at the client until the create for D1 is completed, which it is since we @@ -128,7 +152,8 @@ int main(int argc, char **argv) { as the data that is written. The server returns, along with the data array, a checksum that for the data that is returned. */ - H5Dread(did1, H5T_NATIVE_INT, dataspaceId, dataspaceId, H5P_DEFAULT, r_data); + //H5Dread(did1, H5T_NATIVE_INT, dataspaceId, dataspaceId, H5P_DEFAULT, r_data); + H5Dread_ff(did1, H5T_NATIVE_INT, dataspaceId, dataspaceId, H5P_DEFAULT, r_data, 0, &req1); /* try and print the received buffer before a completion call on the read is issued. @@ -147,7 +172,8 @@ int main(int argc, char **argv) { fail the close. */ dxpl_id = H5Pcreate (H5P_DATASET_XFER); H5Pset_dxpl_inject_bad_checksum(dxpl_id, 1); - H5Dread(did1, H5T_NATIVE_INT, dataspaceId, dataspaceId, dxpl_id, r2_data); + //H5Dread(did1, H5T_NATIVE_INT, dataspaceId, dataspaceId, dxpl_id, r2_data); + H5Dread_ff(did1, H5T_NATIVE_INT, dataspaceId, dataspaceId, dxpl_id, r2_data, 0, &req2); H5Pclose(dxpl_id); H5Sclose(dataspaceId); @@ -211,6 +237,17 @@ int main(int argc, char **argv) { printf("%d ",r2_data[i]); printf("\n"); + assert(H5AOwait(&req1, &status1) == 0); + assert (status1); + assert(H5AOwait(&req2, &status2) == 0); + assert (status2); + assert(H5AOwait(&req6, &status6) == 0); + assert (status6); + assert(H5AOwait(&req7, &status7) == 0); + assert (status7); + assert(H5AOwait(&req8, &status8) == 0); + assert (status8); + free(data); free(r_data); free(data2); @@ -221,7 +258,6 @@ int main(int argc, char **argv) { and shutsdown the FS server (when all clients send the terminate request) and client */ EFF_finalize(); - MPI_Finalize(); return 0; } -- cgit v0.12