From 084b35362bfac78604b02654cdc2067488c00300 Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Fri, 10 May 2002 13:38:10 -0500 Subject: [svn-r5393] Purpose: New Feature Description: The VFL flush function is called immediately before a file is closed. This can cause duplicate syncronization actions to occur, if the VFL close function also performs them. Solution: Added 'closing' parameter to VFL 'flush' operation. This allows the VFL flush function to bypass operations that will be duplicated within the VFL close function. Additionally, use the 'closing' parameter to bypass calls to MPI_File_sync() when set. Since MPI_File_close() also syncronizes the file, this avoids the terrible performance hit taken when calling MPI_File_sync() as the file is closing. Platforms tested: IRIX64 6.5 (modi4) --- src/H5F.c | 28 +++++++++++++++++----------- src/H5FD.c | 8 +++++--- src/H5FDcore.c | 6 +++--- src/H5FDfamily.c | 4 ++-- src/H5FDlog.c | 6 +++--- src/H5FDmpio.c | 14 +++++++++----- src/H5FDmulti.c | 6 +++--- src/H5FDprivate.h | 2 +- src/H5FDpublic.h | 2 +- src/H5FDsec2.c | 6 +++--- src/H5FDsrb.c | 8 ++++---- src/H5FDstdio.c | 12 +++++++----- src/H5FDstream.c | 4 ++-- 13 files changed, 60 insertions(+), 46 deletions(-) diff --git a/src/H5F.c b/src/H5F.c index 35c9822..dc54a82 100644 --- a/src/H5F.c +++ b/src/H5F.c @@ -65,7 +65,7 @@ typedef struct H5F_olist_t { static H5F_t *H5F_new(H5F_file_t *shared, hid_t fcpl_id, hid_t fapl_id); static herr_t H5F_dest(H5F_t *f); static herr_t H5F_flush(H5F_t *f, H5F_scope_t scope, hbool_t invalidate, - hbool_t alloc_only); + hbool_t alloc_only, hbool_t closing); static haddr_t H5F_locate_signature(H5FD_t *file); static int H5F_flush_all_cb(H5F_t *f, hid_t fid, const void *_invalidate); static herr_t H5F_get_obj_count(H5F_t *f, unsigned types, @@ -631,7 +631,7 @@ static int H5F_flush_all_cb(H5F_t *f, hid_t UNUSED fid, const void *_invalidate) { hbool_t invalidate = *((const hbool_t*)_invalidate); - H5F_flush(f, H5F_SCOPE_LOCAL, invalidate, FALSE); + H5F_flush(f, H5F_SCOPE_LOCAL, invalidate, FALSE, FALSE); return 0; } @@ -1747,7 +1747,7 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id) shared->boot_addr = userblock_size; shared->base_addr = shared->boot_addr; shared->consist_flags = 0x03; - if (H5F_flush(file, H5F_SCOPE_LOCAL, FALSE, TRUE)<0) + if (H5F_flush(file, H5F_SCOPE_LOCAL, FALSE, TRUE, FALSE)<0) HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to write file superblock"); /* Create and open the root group */ @@ -2222,7 +2222,7 @@ H5Fflush(hid_t object_id, H5F_scope_t scope) } /* Flush the file */ - if (H5F_flush(f, scope, FALSE, FALSE)<0) { + if (H5F_flush(f, scope, FALSE, FALSE, FALSE)<0) { HRETURN_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "flush failed"); } @@ -2268,11 +2268,17 @@ H5Fflush(hid_t object_id, H5F_scope_t scope) * Raymond Lu, 2001-10-14 * Changed to new generic property list. * + * Quincey Koziol, 2002-05-10 + * Added new 'closing' parameter to indicate that this function + * is being called immediately before a file is closed. This + * may allow some file drivers to bypass duplicating certain + * syncronizations that are already performed when a file + * closes. *------------------------------------------------------------------------- */ static herr_t H5F_flush(H5F_t *f, H5F_scope_t scope, hbool_t invalidate, - hbool_t alloc_only) + hbool_t alloc_only, hbool_t closing) { uint8_t sbuf[2048], dbuf[2048], *p=NULL; unsigned nerrors=0, i; @@ -2303,7 +2309,7 @@ H5F_flush(H5F_t *f, H5F_scope_t scope, hbool_t invalidate, } if (H5F_SCOPE_DOWN==scope) { for (i=0; imtab.nmounts; i++) { - if (H5F_flush(f->mtab.child[i].file, scope, invalidate, FALSE)<0) + if (H5F_flush(f->mtab.child[i].file, scope, invalidate, FALSE, closing)<0) nerrors++; } } @@ -2431,7 +2437,7 @@ H5F_flush(H5F_t *f, H5F_scope_t scope, hbool_t invalidate, } /* end else */ /* Flush file buffers to disk */ - if (!alloc_only && H5FD_flush(f->shared->lf)<0) + if (!alloc_only && H5FD_flush(f->shared->lf, closing)<0) HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "low level flush failed"); /* Check flush errors for children - errors are already on the stack */ @@ -2490,7 +2496,7 @@ H5F_close(H5F_t *f) * count, flush the file, and return. */ if (f->nrefs>1) { - if (H5F_flush(f, H5F_SCOPE_LOCAL, FALSE, FALSE)<0) { + if (H5F_flush(f, H5F_SCOPE_LOCAL, FALSE, FALSE, FALSE)<0) { HRETURN_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush cache"); } @@ -2516,7 +2522,7 @@ H5F_close(H5F_t *f) assert(1==f->nrefs); if (1==f->shared->nrefs) { /* Flush and destroy all caches */ - if (H5F_flush(f, H5F_SCOPE_LOCAL, TRUE, FALSE)<0) { + if (H5F_flush(f, H5F_SCOPE_LOCAL, TRUE, FALSE, TRUE)<0) { HRETURN_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush cache"); } @@ -2551,7 +2557,7 @@ H5F_close(H5F_t *f) * instead. */ if (f->nopen_objs>0) { - if (H5F_flush(f, H5F_SCOPE_LOCAL, FALSE, FALSE)<0) + if (H5F_flush(f, H5F_SCOPE_LOCAL, FALSE, FALSE, TRUE)<0) HRETURN_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush cache"); #ifdef H5F_DEBUG @@ -2619,7 +2625,7 @@ H5F_close(H5F_t *f) * this file are closed the flush isn't really necessary, but lets * just be safe. */ - if (H5F_flush(f, H5F_SCOPE_LOCAL, TRUE, FALSE)<0) { + if (H5F_flush(f, H5F_SCOPE_LOCAL, TRUE, FALSE, FALSE)<0) { HRETURN_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush cache"); } diff --git a/src/H5FD.c b/src/H5FD.c index 8f33140..b30bdd2 100644 --- a/src/H5FD.c +++ b/src/H5FD.c @@ -2487,7 +2487,7 @@ H5FDflush(H5FD_t *file) } /* Do the real work */ - if (H5FD_flush(file)<0) { + if (H5FD_flush(file, FALSE)<0) { HRETURN_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "file flush request failed"); } @@ -2509,11 +2509,13 @@ H5FDflush(H5FD_t *file) * Wednesday, August 4, 1999 * * Modifications: + * Quincey Koziol, 2002-05-10 + * Added 'closing' parameter * *------------------------------------------------------------------------- */ herr_t -H5FD_flush(H5FD_t *file) +H5FD_flush(H5FD_t *file, hbool_t closing) { FUNC_ENTER(H5FD_flush, FAIL); assert(file && file->cls); @@ -2529,7 +2531,7 @@ H5FD_flush(H5FD_t *file) file->accum_dirty=FALSE; } /* end if */ - if (file->cls->flush && (file->cls->flush)(file)<0) + if (file->cls->flush && (file->cls->flush)(file,closing)<0) HRETURN_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "driver flush request failed"); FUNC_LEAVE(SUCCEED); diff --git a/src/H5FDcore.c b/src/H5FDcore.c index 13a4a01..e97e01e 100644 --- a/src/H5FDcore.c +++ b/src/H5FDcore.c @@ -78,7 +78,7 @@ typedef struct H5FD_core_fapl_t { static void *H5FD_core_fapl_get(H5FD_t *_file); static H5FD_t *H5FD_core_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr); -static herr_t H5FD_core_flush(H5FD_t *_file); +static herr_t H5FD_core_flush(H5FD_t *_file, hbool_t closing); static herr_t H5FD_core_close(H5FD_t *_file); static int H5FD_core_cmp(const H5FD_t *_f1, const H5FD_t *_f2); static haddr_t H5FD_core_get_eoa(H5FD_t *_file); @@ -365,7 +365,7 @@ H5FD_core_open(const char *name, unsigned UNUSED flags, hid_t fapl_id, *------------------------------------------------------------------------- */ static herr_t -H5FD_core_flush(H5FD_t *_file) +H5FD_core_flush(H5FD_t *_file, hbool_t UNUSED closing) { H5FD_core_t *file = (H5FD_core_t*)_file; @@ -425,7 +425,7 @@ H5FD_core_close(H5FD_t *_file) FUNC_ENTER(H5FD_core_close, FAIL); /* Flush */ - if (H5FD_core_flush(_file)<0) + if (H5FD_core_flush(_file,TRUE)<0) HRETURN_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "unable to flush file"); /* Release resources */ diff --git a/src/H5FDfamily.c b/src/H5FDfamily.c index 7c1bfab..acd68a5 100644 --- a/src/H5FDfamily.c +++ b/src/H5FDfamily.c @@ -81,7 +81,7 @@ static herr_t H5FD_family_read(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id, ha size_t size, void *_buf/*out*/); static herr_t H5FD_family_write(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, size_t size, const void *_buf); -static herr_t H5FD_family_flush(H5FD_t *_file); +static herr_t H5FD_family_flush(H5FD_t *_file, hbool_t closing); /* The class struct */ static const H5FD_class_t H5FD_family_g = { @@ -1009,7 +1009,7 @@ H5FD_family_write(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, s *------------------------------------------------------------------------- */ static herr_t -H5FD_family_flush(H5FD_t *_file) +H5FD_family_flush(H5FD_t *_file, hbool_t UNUSED closing) { H5FD_family_t *file = (H5FD_family_t*)_file; int i, nerrors=0; diff --git a/src/H5FDlog.c b/src/H5FDlog.c index 23a3943..4548351 100644 --- a/src/H5FDlog.c +++ b/src/H5FDlog.c @@ -175,7 +175,7 @@ static herr_t H5FD_log_read(H5FD_t *_file, H5FD_mem_t type, hid_t fapl_id, haddr size_t size, void *buf); static herr_t H5FD_log_write(H5FD_t *_file, H5FD_mem_t type, hid_t fapl_id, haddr_t addr, size_t size, const void *buf); -static herr_t H5FD_log_flush(H5FD_t *_file); +static herr_t H5FD_log_flush(H5FD_t *_file, hbool_t closing); /* * The free list map which causes each request type to use no free lists @@ -581,7 +581,7 @@ H5FD_log_close(H5FD_t *_file) FUNC_ENTER(H5FD_log_close, FAIL); - if (H5FD_log_flush(_file)<0) + if (H5FD_log_flush(_file,TRUE)<0) HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "unable to flush file"); #ifdef H5_HAVE_GETTIMEOFDAY @@ -1212,7 +1212,7 @@ H5FD_log_write(H5FD_t *_file, H5FD_mem_t type, hid_t UNUSED dxpl_id, haddr_t add *------------------------------------------------------------------------- */ static herr_t -H5FD_log_flush(H5FD_t *_file) +H5FD_log_flush(H5FD_t *_file, hbool_t UNUSED closing) { H5FD_log_t *file = (H5FD_log_t*)_file; diff --git a/src/H5FDmpio.c b/src/H5FDmpio.c index 2d28828..9be69f6 100644 --- a/src/H5FDmpio.c +++ b/src/H5FDmpio.c @@ -83,7 +83,7 @@ static herr_t H5FD_mpio_read(H5FD_t *_file, H5FD_mem_t type, hid_t fapl_id, hadd size_t size, void *buf); static herr_t H5FD_mpio_write(H5FD_t *_file, H5FD_mem_t type, hid_t fapl_id, haddr_t addr, size_t size, const void *buf); -static herr_t H5FD_mpio_flush(H5FD_t *_file); +static herr_t H5FD_mpio_flush(H5FD_t *_file, hbool_t closing); /* MPIO-specific file access properties */ typedef struct H5FD_mpio_fapl_t { @@ -1521,7 +1521,7 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5FD_mpio_flush(H5FD_t *_file) +H5FD_mpio_flush(H5FD_t *_file, hbool_t closing) { H5FD_mpio_t *file = (H5FD_mpio_t*)_file; int mpi_code; /* mpi return code */ @@ -1563,9 +1563,13 @@ H5FD_mpio_flush(H5FD_t *_file) } } - - if (MPI_SUCCESS != (mpi_code=MPI_File_sync(file->f))) - HMPI_GOTO_ERROR(FAIL, "MPI_File_sync failed", mpi_code); + /* Don't bother calling MPI_File_sync() if we are going to immediately + * close the file, MPI_File_close() performs the same sync actions. + */ + if(!closing) { + if (MPI_SUCCESS != (mpi_code=MPI_File_sync(file->f))) + HMPI_GOTO_ERROR(FAIL, "MPI_File_sync failed", mpi_code); + } /* end if */ done: #ifdef H5FDmpio_DEBUG diff --git a/src/H5FDmulti.c b/src/H5FDmulti.c index 901e379..ad7f4db 100644 --- a/src/H5FDmulti.c +++ b/src/H5FDmulti.c @@ -129,7 +129,7 @@ static herr_t H5FD_multi_read(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id, had size_t size, void *_buf/*out*/); static herr_t H5FD_multi_write(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, size_t size, const void *_buf); -static herr_t H5FD_multi_flush(H5FD_t *_file); +static herr_t H5FD_multi_flush(H5FD_t *_file, hbool_t closing); /* The class struct */ static const H5FD_class_t H5FD_multi_g = { @@ -1254,7 +1254,7 @@ H5FD_multi_close(H5FD_t *_file) H5Eclear(); /* Flush our own data */ - if (H5FD_multi_flush(_file)<0) + if (H5FD_multi_flush(_file,TRUE)<0) nerrors++; /* Close as many members as possible */ @@ -1712,7 +1712,7 @@ H5FD_multi_write(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, si *------------------------------------------------------------------------- */ static herr_t -H5FD_multi_flush(H5FD_t *_file) +H5FD_multi_flush(H5FD_t *_file, hbool_t closing) { H5FD_multi_t *file = (H5FD_multi_t*)_file; H5FD_mem_t mt; diff --git a/src/H5FDprivate.h b/src/H5FDprivate.h index 6e0c919..cd9feb1 100644 --- a/src/H5FDprivate.h +++ b/src/H5FDprivate.h @@ -38,7 +38,7 @@ __DLL__ herr_t H5FD_read(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t a void *buf/*out*/); __DLL__ herr_t H5FD_write(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, size_t size, const void *buf); -__DLL__ herr_t H5FD_flush(H5FD_t *file); +__DLL__ herr_t H5FD_flush(H5FD_t *file, hbool_t closing); __DLL__ herr_t H5FD_get_fileno(const H5FD_t *file, unsigned long *filenum); #endif /* !_H5FDprivate_H */ diff --git a/src/H5FDpublic.h b/src/H5FDpublic.h index 81a63f5..4769cac 100644 --- a/src/H5FDpublic.h +++ b/src/H5FDpublic.h @@ -135,7 +135,7 @@ typedef struct H5FD_class_t { void *buffer); herr_t (*write)(H5FD_t *file, H5FD_mem_t type, hid_t dxpl, haddr_t addr, size_t size, const void *buffer); - herr_t (*flush)(H5FD_t *file); + herr_t (*flush)(H5FD_t *file, hbool_t closing); H5FD_mem_t fl_map[H5FD_MEM_NTYPES]; } H5FD_class_t; diff --git a/src/H5FDsec2.c b/src/H5FDsec2.c index 986906d..3469fc3 100644 --- a/src/H5FDsec2.c +++ b/src/H5FDsec2.c @@ -144,7 +144,7 @@ static herr_t H5FD_sec2_read(H5FD_t *_file, H5FD_mem_t type, hid_t fapl_id, hadd size_t size, void *buf); static herr_t H5FD_sec2_write(H5FD_t *_file, H5FD_mem_t type, hid_t fapl_id, haddr_t addr, size_t size, const void *buf); -static herr_t H5FD_sec2_flush(H5FD_t *_file); +static herr_t H5FD_sec2_flush(H5FD_t *_file, hbool_t closing); static const H5FD_class_t H5FD_sec2_g = { "sec2", /*name */ @@ -347,7 +347,7 @@ H5FD_sec2_close(H5FD_t *_file) FUNC_ENTER(H5FD_sec2_close, FAIL); - if (H5FD_sec2_flush(_file)<0) + if (H5FD_sec2_flush(_file,TRUE)<0) HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "unable to flush file"); if (close(file->fd)<0) HRETURN_ERROR(H5E_IO, H5E_CANTCLOSEFILE, FAIL, "unable to close file"); @@ -717,7 +717,7 @@ H5FD_sec2_write(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, had *------------------------------------------------------------------------- */ static herr_t -H5FD_sec2_flush(H5FD_t *_file) +H5FD_sec2_flush(H5FD_t *_file, hbool_t UNUSED closing) { H5FD_sec2_t *file = (H5FD_sec2_t*)_file; diff --git a/src/H5FDsrb.c b/src/H5FDsrb.c index 7b92ec7..7a2c978 100644 --- a/src/H5FDsrb.c +++ b/src/H5FDsrb.c @@ -90,7 +90,7 @@ static herr_t H5FD_srb_read(H5FD_t *_file, H5FD_mem_t type, hid_t fapl_id, hadd size_t size, void *buf); static herr_t H5FD_srb_write(H5FD_t *_file, H5FD_mem_t type, hid_t fapl_id, haddr_t addr, size_t size, const void *buf); -static herr_t H5FD_srb_flush(H5FD_t *_file); +static herr_t H5FD_srb_flush(H5FD_t *_file, hbool_t closing); /* The description of a file belonging to this driver. */ typedef struct H5FD_srb_t { @@ -662,12 +662,12 @@ H5FD_srb_write(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, hadd *------------------------------------------------------------------------- */ static herr_t -H5FD_srb_flush(H5FD_t *_file) +H5FD_srb_flush(H5FD_t *_file, hbool_t UNUSED closing) { H5FD_srb_t *file = (H5FD_srb_t*)_file; - /*why H5FD_family_flush?*/ - FUNC_ENTER(H5FD_family_flush, FAIL); + FUNC_ENTER(H5FD_srb_flush, FAIL); + if(srbFileSync(file->srb_conn, file->fd) != 0) { srbFileClose(file->srb_conn, file->fd); clFinish(file->srb_conn); diff --git a/src/H5FDstdio.c b/src/H5FDstdio.c index 4085de7..0599431 100644 --- a/src/H5FDstdio.c +++ b/src/H5FDstdio.c @@ -141,7 +141,7 @@ static herr_t H5FD_stdio_read(H5FD_t *lf, H5FD_mem_t type, hid_t fapl_id, haddr_ size_t size, void *buf); static herr_t H5FD_stdio_write(H5FD_t *lf, H5FD_mem_t type, hid_t fapl_id, haddr_t addr, size_t size, const void *buf); -static herr_t H5FD_stdio_flush(H5FD_t *_file); +static herr_t H5FD_stdio_flush(H5FD_t *_file, hbool_t closing); static const H5FD_class_t H5FD_stdio_g = { "stdio", /*name */ @@ -376,7 +376,7 @@ H5FD_stdio_close(H5FD_t *_file) /* Clear the error stack */ H5Eclear(); - if (H5FD_stdio_flush(_file)<0) + if (H5FD_stdio_flush(_file,1)<0) H5Epush_ret(func, H5E_IO, H5E_WRITEERROR, "flush failed", -1); if (fclose(file->fp) < 0) H5Epush_ret(func, H5E_IO, H5E_CLOSEERROR, "fclose failed", -1); @@ -797,7 +797,7 @@ H5FD_stdio_write(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, *------------------------------------------------------------------------- */ static herr_t -H5FD_stdio_flush(H5FD_t *_file) +H5FD_stdio_flush(H5FD_t *_file, hbool_t closing) { H5FD_stdio_t *file = (H5FD_stdio_t*)_file; static const char *func="H5FD_stdio_flush"; /* Function Name for error reporting */ @@ -827,8 +827,10 @@ H5FD_stdio_flush(H5FD_t *_file) /* * Flush */ - if (fflush(file->fp) < 0) - H5Epush_ret(func, H5E_IO, H5E_WRITEERROR, "fflush failed", -1); + if(!closing) { + if (fflush(file->fp) < 0) + H5Epush_ret(func, H5E_IO, H5E_WRITEERROR, "fflush failed", -1); + } /* end if */ } /* end if */ else { /* Double-check for problems */ diff --git a/src/H5FDstream.c b/src/H5FDstream.c index ed7035e..ac38c45 100644 --- a/src/H5FDstream.c +++ b/src/H5FDstream.c @@ -153,7 +153,7 @@ static const H5FD_stream_fapl_t default_fapl = static void *H5FD_stream_fapl_get (H5FD_t *_stream); static H5FD_t *H5FD_stream_open (const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr); -static herr_t H5FD_stream_flush (H5FD_t *_stream); +static herr_t H5FD_stream_flush (H5FD_t *_stream, hbool_t closing); static herr_t H5FD_stream_close (H5FD_t *_stream); static herr_t H5FD_stream_query(const H5FD_t *_f1, unsigned long *flags); static haddr_t H5FD_stream_get_eoa (H5FD_t *_stream); @@ -813,7 +813,7 @@ static H5FD_t *H5FD_stream_open (const char *filename, * *------------------------------------------------------------------------- */ -static herr_t H5FD_stream_flush (H5FD_t *_stream) +static herr_t H5FD_stream_flush (H5FD_t *_stream, hbool_t UNUSED closing) { H5FD_stream_t *stream = (H5FD_stream_t *) _stream; size_t size; -- cgit v0.12