[Darshan-commits] [Git][darshan/darshan][master] 57 commits: skeleton stubs for stdio module
Shane Snyder
xgitlab at cels.anl.gov
Wed Jul 6 17:51:47 CDT 2016
Shane Snyder pushed to branch master at darshan / darshan
Commits:
78ebc882 by Phil Carns at 2016-04-14T15:42:50-04:00
skeleton stubs for stdio module
- - - - -
8efca566 by Phil Carns at 2016-04-14T17:26:05-04:00
taking note of what functions we may need to catch
- - - - -
ebbe6421 by Phil Carns at 2016-04-19T12:01:32-04:00
initial skeleton for stdio wrapper lib
- move fopen/fopen64 wrappers to stdio module
- make infrastructure for tracking stream pointers based on similar fd
infrastructure in posix
- define placeholder record structs
- wrappers don't actually do anything yet
- - - - -
db5a2150 by Phil Carns at 2016-04-29T15:20:39-04:00
Merge remote-tracking branch 'origin/master' into dev-stdio
- - - - -
4fd93356 by Phil Carns at 2016-04-29T15:39:07-04:00
add missing file from previous commits
- - - - -
28131252 by Phil Carns at 2016-04-29T17:22:27-04:00
start filling in fopen counters
- - - - -
841429de by Phil Carns at 2016-04-29T17:31:41-04:00
get utils working for stdio module
- - - - -
8d3a2c8a by Phil Carns at 2016-05-01T07:58:33-04:00
Merge remote-tracking branch 'origin/master' into dev-stdio
- - - - -
96247ec9 by Phil Carns at 2016-05-01T07:59:39-04:00
remove old TODO comment
- - - - -
76c86577 by Phil Carns at 2016-05-01T08:20:31-04:00
stub regression test for stdio module
- - - - -
585615f9 by Phil Carns at 2016-05-01T08:30:30-04:00
check more stdio counters in regression
- - - - -
7e58577d by Phil Carns at 2016-05-01T08:34:19-04:00
fopen64 wrapper
- - - - -
29b23f7e by Phil Carns at 2016-05-01T09:00:35-04:00
move fclose wrapper to stdio module
- - - - -
107937f1 by Phil Carns at 2016-05-01T09:03:46-04:00
start tracking which symbols have been captured
- - - - -
7e1b6e91 by Phil Carns at 2016-05-01T09:51:05-04:00
move fwrite wrapper to stdio module
- - - - -
f3b3ba9a by Phil Carns at 2016-05-01T09:56:34-04:00
Merge remote-tracking branch 'origin/master' into dev-stdio
- - - - -
25833864 by Phil Carns at 2016-05-01T09:57:11-04:00
remove old reminder comment
- - - - -
da685755 by Phil Carns at 2016-05-01T10:21:19-04:00
move fread wrapper to stdio module
- - - - -
91092ee1 by Phil Carns at 2016-05-01T10:32:14-04:00
move fseek wrapper to stdio module
- - - - -
af624bef by Phil Carns at 2016-05-01T10:39:58-04:00
misc code cleanups and notes
- - - - -
9a13bcc0 by Phil Carns at 2016-05-18T17:15:35-05:00
comments
- - - - -
11c80b44 by Phil Carns at 2016-05-18T17:17:52-05:00
move comments
- - - - -
9930d72a by Phil Carns at 2016-05-23T20:38:32-04:00
fdopen wrapper
- - - - -
e025a97f by Phil Carns at 2016-05-23T20:42:01-04:00
freopen wrapper
- - - - -
9781671b by Phil Carns at 2016-05-23T20:50:05-04:00
fflush wrapper
- - - - -
4cdf8a06 by Phil Carns at 2016-05-23T20:53:18-04:00
fgetc wrapper
- - - - -
da08451f by Phil Carns at 2016-05-23T20:57:07-04:00
fgets wrapper
- - - - -
9e6663d9 by Phil Carns at 2016-05-23T21:13:46-04:00
fscanf and vfscanf wrappers
- needs testing
- - - - -
551c339c by Phil Carns at 2016-05-23T21:18:51-04:00
getc wrapper
- - - - -
05a68fd0 by Phil Carns at 2016-05-23T21:23:11-04:00
skip the unlocked functions
- - - - -
d4fc0944 by Phil Carns at 2016-05-23T21:26:48-04:00
getw wrapper
- - - - -
c2a08740 by Phil Carns at 2016-05-23T22:37:10-04:00
fprintf wrapper
- - - - -
09926b48 by Phil Carns at 2016-05-23T22:51:39-04:00
fputc wrapper
- - - - -
3b4bef1d by Phil Carns at 2016-05-23T22:54:37-04:00
fputs wrapper
- - - - -
d094097c by Phil Carns at 2016-05-23T22:57:57-04:00
putc wrapper
- - - - -
29641b6a by Phil Carns at 2016-05-23T23:00:21-04:00
putw wrapper
- - - - -
9697f099 by Phil Carns at 2016-05-23T23:03:11-04:00
fseeko wrapper
- - - - -
6c43ebe8 by Phil Carns at 2016-05-23T23:05:21-04:00
add missing 64 bit variants
- - - - -
0461e398 by Phil Carns at 2016-05-23T23:18:54-04:00
freopen64 wrapper
- - - - -
93a0e7a1 by Phil Carns at 2016-05-23T23:20:13-04:00
fseeko64 wrapper
- - - - -
0289d4ab by Phil Carns at 2016-05-23T23:24:12-04:00
fsetpos and fsetpos64 wrappers
- - - - -
904b6dbc by Phil Carns at 2016-05-23T23:26:29-04:00
rewind wrapper
- - - - -
4b1dcbb5 by Phil Carns at 2016-05-23T23:27:48-04:00
on second thought, let's not mess with ungetc
- - - - -
5fd3c5c1 by Phil Carns at 2016-05-23T23:28:46-04:00
update comments
- - - - -
3d7cc3c6 by Phil Carns at 2016-05-24T16:54:43-04:00
implement shared reduction for stdio records
- - - - -
106767d3 by Phil Carns at 2016-05-24T17:30:40-04:00
update test case to account for shared reduction
- - - - -
9cd5e5c0 by Phil Carns at 2016-05-27T17:16:33-04:00
get fscanf working
- includes regression test for fprintf and fscanf
- apparently you have to wrap __isoc99_fscanf instead of fscanf
sometimes
- - - - -
1a67e237 by Phil Carns at 2016-06-22T14:53:53-04:00
Merge remote-tracking branch 'origin/master' into dev-stdio
- note: darshan-stdio module updates are still needed; this merge just
updates the rest of the code and resolves conflicts
- - - - -
ad6ea64f by Phil Carns at 2016-06-23T17:33:59-04:00
convert stdio module to use new apis
- eliminated 110 SLOC
- untested
- - - - -
af5dfe77 by Phil Carns at 2016-06-24T12:44:27-04:00
update stdio module logutils to match new apis
- - - - -
9d18599a by Phil Carns at 2016-06-24T12:51:40-04:00
typo
- - - - -
112b403f by Phil Carns at 2016-06-24T13:00:15-04:00
bug fix, transposed arguments to mod register
- - - - -
8bb4890f by Phil Carns at 2016-06-24T13:15:28-04:00
cleanup sizeof calls
- - - - -
ebb9ba17 by Phil Carns at 2016-06-24T13:32:37-04:00
fix another sizeof bug
- - - - -
06b84605 by Phil Carns at 2016-06-30T15:05:31-04:00
comment update
- - - - -
5c5f5334 by Shane Snyder at 2016-07-06T13:12:32-05:00
Merge branch 'dev-stdio'
Conflicts:
darshan-log-format.h
darshan-runtime/Makefile.in
darshan-util/Makefile.in
darshan-util/darshan-logutils.h
- - - - -
5c5e4452 by Shane Snyder at 2016-07-06T13:15:33-05:00
fix prototypes for a few stdio funcs
- - - - -
20 changed files:
- darshan-log-format.h
- darshan-runtime/Makefile.in
- darshan-runtime/configure
- darshan-runtime/darshan-runtime-config.h.in
- darshan-runtime/lib/darshan-posix.c
- + darshan-runtime/lib/darshan-stdio.c
- darshan-runtime/share/ld-opts/darshan-base-ld-opts.in
- darshan-runtime/share/ld-opts/darshan-posix-ld-opts
- + darshan-runtime/share/ld-opts/darshan-stdio-ld-opts
- + darshan-stdio-log-format.h
- + darshan-test/regression/test-cases/fprintf-fscanf-test.sh
- + darshan-test/regression/test-cases/src/fprintf-fscanf-test.c
- + darshan-test/regression/test-cases/src/stdio-test.c
- + darshan-test/regression/test-cases/stdio-test.sh
- darshan-util/Makefile.in
- darshan-util/configure
- darshan-util/darshan-logutils.h
- + darshan-util/darshan-stdio-logutils.c
- + darshan-util/darshan-stdio-logutils.h
- darshan-util/darshan-util-config.h.in
Changes:
=====================================
darshan-log-format.h
=====================================
--- a/darshan-log-format.h
+++ b/darshan-log-format.h
@@ -112,6 +112,7 @@ struct darshan_base_record
#include "darshan-pnetcdf-log-format.h"
#include "darshan-bgq-log-format.h"
#include "darshan-lustre-log-format.h"
+#include "darshan-stdio-log-format.h"
/* X-macro for keeping module ordering consistent */
/* NOTE: first val used to define module enum values,
@@ -130,7 +131,8 @@ struct darshan_base_record
X(DARSHAN_HDF5_MOD, "HDF5", DARSHAN_HDF5_VER, &hdf5_logutils) \
X(DARSHAN_PNETCDF_MOD, "PNETCDF", DARSHAN_PNETCDF_VER, &pnetcdf_logutils) \
X(DARSHAN_BGQ_MOD, "BG/Q", DARSHAN_BGQ_VER, &bgq_logutils) \
- X(DARSHAN_LUSTRE_MOD, "LUSTRE", DARSHAN_LUSTRE_VER, &lustre_logutils)
+ X(DARSHAN_LUSTRE_MOD, "LUSTRE", DARSHAN_LUSTRE_VER, &lustre_logutils) \
+ X(DARSHAN_STDIO_MOD, "STDIO", DARSHAN_STDIO_VER, &stdio_logutils)
/* unique identifiers to distinguish between available darshan modules */
/* NOTES: - valid ids range from [0...DARSHAN_MAX_MODS-1]
=====================================
darshan-runtime/Makefile.in
=====================================
--- a/darshan-runtime/Makefile.in
+++ b/darshan-runtime/Makefile.in
@@ -35,8 +35,8 @@ CFLAGS_SHARED = -DDARSHAN_CONFIG_H=\"darshan-runtime-config.h\" -I . -I$(srcdir)
LIBS = -lz @LIBBZ2@
-DARSHAN_STATIC_MOD_OBJS = lib/darshan-posix.o lib/darshan-mpiio.o lib/darshan-hdf5.o lib/darshan-pnetcdf.o
-DARSHAN_DYNAMIC_MOD_OBJS = lib/darshan-posix.po lib/darshan-mpiio.po lib/darshan-hdf5.po lib/darshan-pnetcdf.po
+DARSHAN_STATIC_MOD_OBJS = lib/darshan-posix.o lib/darshan-mpiio.o lib/darshan-hdf5.o lib/darshan-pnetcdf.o lib/darshan-stdio.o
+DARSHAN_DYNAMIC_MOD_OBJS = lib/darshan-posix.po lib/darshan-mpiio.po lib/darshan-hdf5.po lib/darshan-pnetcdf.po lib/darshan-stdio.po
ifdef DARSHAN_USE_BGQ
DARSHAN_STATIC_MOD_OBJS += lib/darshan-bgq.o
@@ -121,6 +121,12 @@ lib/darshan-lustre.o: lib/darshan-lustre.c darshan-lustre.h darshan.h darshan-co
lib/darshan-lustre.po: lib/darshan-lustre.c darshan-lustre.h darshan.h darshan-dynamic.h darshan-common.h $(DARSHAN_LOG_FORMAT) $(srcdir)/../darshan-lustre-log-format.h | lib
$(CC) $(CFLAGS_SHARED) -c $< -o $@
+lib/darshan-stdio.o: lib/darshan-stdio.c darshan.h darshan-common.h $(DARSHAN_LOG_FORMAT) $(srcdir)/../darshan-stdio-log-format.h | lib
+ $(CC) $(CFLAGS) -c $< -o $@
+
+lib/darshan-stdio.po: lib/darshan-stdio.c darshan.h darshan-dynamic.h darshan-common.h $(DARSHAN_LOG_FORMAT) $(srcdir)/../darshan-stdio-log-format.h | lib
+ $(CC) $(CFLAGS_SHARED) -c $< -o $@
+
lib/lookup3.o: lib/lookup3.c
$(CC) $(CFLAGS) -c $< -o $@
@@ -172,6 +178,7 @@ endif
install -m 644 $(srcdir)/share/ld-opts/darshan-posix-ld-opts $(datarootdir)/ld-opts/darshan-posix-ld-opts
install -m 644 $(srcdir)/share/ld-opts/darshan-hdf5-ld-opts $(datarootdir)/ld-opts/darshan-hdf5-ld-opts
install -m 644 $(srcdir)/share/ld-opts/darshan-pnetcdf-ld-opts $(datarootdir)/ld-opts/darshan-pnetcdf-ld-opts
+ install -m 644 $(srcdir)/share/ld-opts/darshan-stdio-ld-opts $(datarootdir)/ld-opts/darshan-stdio-ld-opts
ifdef ENABLE_MMAP_LOGS
install -m 755 share/darshan-mmap-epilog.sh $(datarootdir)/darshan-mmap-epilog.sh
endif
=====================================
darshan-runtime/configure
=====================================
The diff for this file was not included because it is too large.
=====================================
darshan-runtime/darshan-runtime-config.h.in
=====================================
--- a/darshan-runtime/darshan-runtime-config.h.in
+++ b/darshan-runtime/darshan-runtime-config.h.in
@@ -60,6 +60,9 @@
/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME
+/* Define to the home page for this package. */
+#undef PACKAGE_URL
+
/* Define to the version of this package. */
#undef PACKAGE_VERSION
=====================================
darshan-runtime/lib/darshan-posix.c
=====================================
--- a/darshan-runtime/lib/darshan-posix.c
+++ b/darshan-runtime/lib/darshan-posix.c
@@ -45,8 +45,6 @@ DARSHAN_FORWARD_DECL(open, int, (const char *path, int flags, ...));
DARSHAN_FORWARD_DECL(open64, int, (const char *path, int flags, ...));
DARSHAN_FORWARD_DECL(creat, int, (const char* path, mode_t mode));
DARSHAN_FORWARD_DECL(creat64, int, (const char* path, mode_t mode));
-DARSHAN_FORWARD_DECL(fopen, FILE*, (const char *path, const char *mode));
-DARSHAN_FORWARD_DECL(fopen64, FILE*, (const char *path, const char *mode));
DARSHAN_FORWARD_DECL(mkstemp, int, (char *template));
DARSHAN_FORWARD_DECL(mkostemp, int, (char *template, int flags));
DARSHAN_FORWARD_DECL(mkstemps, int, (char *template, int suffixlen));
@@ -59,11 +57,8 @@ DARSHAN_FORWARD_DECL(pread64, ssize_t, (int fd, void *buf, size_t count, off64_t
DARSHAN_FORWARD_DECL(pwrite64, ssize_t, (int fd, const void *buf, size_t count, off64_t offset));
DARSHAN_FORWARD_DECL(readv, ssize_t, (int fd, const struct iovec *iov, int iovcnt));
DARSHAN_FORWARD_DECL(writev, ssize_t, (int fd, const struct iovec *iov, int iovcnt));
-DARSHAN_FORWARD_DECL(fread, size_t, (void *ptr, size_t size, size_t nmemb, FILE *stream));
-DARSHAN_FORWARD_DECL(fwrite, size_t, (const void *ptr, size_t size, size_t nmemb, FILE *stream));
DARSHAN_FORWARD_DECL(lseek, off_t, (int fd, off_t offset, int whence));
DARSHAN_FORWARD_DECL(lseek64, off64_t, (int fd, off64_t offset, int whence));
-DARSHAN_FORWARD_DECL(fseek, int, (FILE *stream, long offset, int whence));
DARSHAN_FORWARD_DECL(__xstat, int, (int vers, const char* path, struct stat *buf));
DARSHAN_FORWARD_DECL(__xstat64, int, (int vers, const char* path, struct stat64 *buf));
DARSHAN_FORWARD_DECL(__lxstat, int, (int vers, const char* path, struct stat *buf));
@@ -75,7 +70,6 @@ DARSHAN_FORWARD_DECL(mmap64, void*, (void *addr, size_t length, int prot, int fl
DARSHAN_FORWARD_DECL(fsync, int, (int fd));
DARSHAN_FORWARD_DECL(fdatasync, int, (int fd));
DARSHAN_FORWARD_DECL(close, int, (int fd));
-DARSHAN_FORWARD_DECL(fclose, int, (FILE *fp));
DARSHAN_FORWARD_DECL(aio_read, int, (struct aiocb *aiocbp));
DARSHAN_FORWARD_DECL(aio_write, int, (struct aiocb *aiocbp));
DARSHAN_FORWARD_DECL(aio_read64, int, (struct aiocb64 *aiocbp));
@@ -197,7 +191,7 @@ static int darshan_mem_alignment = 1;
POSIX_UNLOCK(); \
} while(0)
-#define POSIX_RECORD_OPEN(__ret, __path, __mode, __stream_flag, __tm1, __tm2) do { \
+#define POSIX_RECORD_OPEN(__ret, __path, __mode, __tm1, __tm2) do { \
darshan_record_id rec_id; \
struct posix_file_record_ref *rec_ref; \
char *newpath; \
@@ -220,10 +214,7 @@ static int darshan_mem_alignment = 1;
rec_ref->offset = 0; \
rec_ref->last_byte_written = 0; \
rec_ref->last_byte_read = 0; \
- if(__stream_flag)\
- rec_ref->file_rec->counters[POSIX_FOPENS] += 1; \
- else \
- rec_ref->file_rec->counters[POSIX_OPENS] += 1; \
+ rec_ref->file_rec->counters[POSIX_OPENS] += 1; \
if(rec_ref->file_rec->fcounters[POSIX_F_OPEN_TIMESTAMP] == 0 || \
rec_ref->file_rec->fcounters[POSIX_F_OPEN_TIMESTAMP] > __tm1) \
rec_ref->file_rec->fcounters[POSIX_F_OPEN_TIMESTAMP] = __tm1; \
@@ -234,7 +225,7 @@ static int darshan_mem_alignment = 1;
if(newpath != __path) free(newpath); \
} while(0)
-#define POSIX_RECORD_READ(__ret, __fd, __pread_flag, __pread_offset, __aligned, __stream_flag, __tm1, __tm2) do { \
+#define POSIX_RECORD_READ(__ret, __fd, __pread_flag, __pread_offset, __aligned, __tm1, __tm2) do { \
struct posix_file_record_ref* rec_ref; \
size_t stride; \
int64_t this_offset; \
@@ -261,10 +252,7 @@ static int darshan_mem_alignment = 1;
if(rec_ref->file_rec->counters[POSIX_MAX_BYTE_READ] < (this_offset + __ret - 1)) \
rec_ref->file_rec->counters[POSIX_MAX_BYTE_READ] = (this_offset + __ret - 1); \
rec_ref->file_rec->counters[POSIX_BYTES_READ] += __ret; \
- if(__stream_flag) \
- rec_ref->file_rec->counters[POSIX_FREADS] += 1; \
- else \
- rec_ref->file_rec->counters[POSIX_READS] += 1; \
+ rec_ref->file_rec->counters[POSIX_READS] += 1; \
DARSHAN_BUCKET_INC(&(rec_ref->file_rec->counters[POSIX_SIZE_READ_0_100]), __ret); \
darshan_common_val_counter(&rec_ref->access_root, &rec_ref->access_count, __ret, \
&(rec_ref->file_rec->counters[POSIX_ACCESS1_ACCESS]), \
@@ -291,7 +279,7 @@ static int darshan_mem_alignment = 1;
__tm1, __tm2, rec_ref->last_read_end); \
} while(0)
-#define POSIX_RECORD_WRITE(__ret, __fd, __pwrite_flag, __pwrite_offset, __aligned, __stream_flag, __tm1, __tm2) do { \
+#define POSIX_RECORD_WRITE(__ret, __fd, __pwrite_flag, __pwrite_offset, __aligned, __tm1, __tm2) do { \
struct posix_file_record_ref* rec_ref; \
size_t stride; \
int64_t this_offset; \
@@ -318,10 +306,7 @@ static int darshan_mem_alignment = 1;
if(rec_ref->file_rec->counters[POSIX_MAX_BYTE_WRITTEN] < (this_offset + __ret - 1)) \
rec_ref->file_rec->counters[POSIX_MAX_BYTE_WRITTEN] = (this_offset + __ret - 1); \
rec_ref->file_rec->counters[POSIX_BYTES_WRITTEN] += __ret; \
- if(__stream_flag) \
- rec_ref->file_rec->counters[POSIX_FWRITES] += 1; \
- else \
- rec_ref->file_rec->counters[POSIX_WRITES] += 1; \
+ rec_ref->file_rec->counters[POSIX_WRITES] += 1; \
DARSHAN_BUCKET_INC(&(rec_ref->file_rec->counters[POSIX_SIZE_WRITE_0_100]), __ret); \
darshan_common_val_counter(&rec_ref->access_root, &rec_ref->access_count, __ret, \
&(rec_ref->file_rec->counters[POSIX_ACCESS1_ACCESS]), \
@@ -404,7 +389,7 @@ int DARSHAN_DECL(open)(const char *path, int flags, ...)
}
POSIX_PRE_RECORD();
- POSIX_RECORD_OPEN(ret, path, mode, 0, tm1, tm2);
+ POSIX_RECORD_OPEN(ret, path, mode, tm1, tm2);
POSIX_POST_RECORD();
return(ret);
@@ -437,7 +422,7 @@ int DARSHAN_DECL(open64)(const char *path, int flags, ...)
}
POSIX_PRE_RECORD();
- POSIX_RECORD_OPEN(ret, path, mode, 0, tm1, tm2);
+ POSIX_RECORD_OPEN(ret, path, mode, tm1, tm2);
POSIX_POST_RECORD();
return(ret);
@@ -455,7 +440,7 @@ int DARSHAN_DECL(creat)(const char* path, mode_t mode)
tm2 = darshan_core_wtime();
POSIX_PRE_RECORD();
- POSIX_RECORD_OPEN(ret, path, mode, 0, tm1, tm2);
+ POSIX_RECORD_OPEN(ret, path, mode, tm1, tm2);
POSIX_POST_RECORD();
return(ret);
@@ -473,55 +458,7 @@ int DARSHAN_DECL(creat64)(const char* path, mode_t mode)
tm2 = darshan_core_wtime();
POSIX_PRE_RECORD();
- POSIX_RECORD_OPEN(ret, path, mode, 0, tm1, tm2);
- POSIX_POST_RECORD();
-
- return(ret);
-}
-
-FILE* DARSHAN_DECL(fopen)(const char *path, const char *mode)
-{
- FILE* ret;
- int fd;
- double tm1, tm2;
-
- MAP_OR_FAIL(fopen);
-
- tm1 = darshan_core_wtime();
- ret = __real_fopen(path, mode);
- tm2 = darshan_core_wtime();
-
- if(ret == NULL)
- fd = -1;
- else
- fd = fileno(ret);
-
- POSIX_PRE_RECORD();
- POSIX_RECORD_OPEN(fd, path, 0, 1, tm1, tm2);
- POSIX_POST_RECORD();
-
- return(ret);
-}
-
-FILE* DARSHAN_DECL(fopen64)(const char *path, const char *mode)
-{
- FILE* ret;
- int fd;
- double tm1, tm2;
-
- MAP_OR_FAIL(fopen64);
-
- tm1 = darshan_core_wtime();
- ret = __real_fopen64(path, mode);
- tm2 = darshan_core_wtime();
-
- if(ret == NULL)
- fd = -1;
- else
- fd = fileno(ret);
-
- POSIX_PRE_RECORD();
- POSIX_RECORD_OPEN(fd, path, 0, 1, tm1, tm2);
+ POSIX_RECORD_OPEN(ret, path, mode, tm1, tm2);
POSIX_POST_RECORD();
return(ret);
@@ -539,7 +476,7 @@ int DARSHAN_DECL(mkstemp)(char* template)
tm2 = darshan_core_wtime();
POSIX_PRE_RECORD();
- POSIX_RECORD_OPEN(ret, template, 0, 0, tm1, tm2);
+ POSIX_RECORD_OPEN(ret, template, 0, tm1, tm2);
POSIX_POST_RECORD();
return(ret);
@@ -557,7 +494,7 @@ int DARSHAN_DECL(mkostemp)(char* template, int flags)
tm2 = darshan_core_wtime();
POSIX_PRE_RECORD();
- POSIX_RECORD_OPEN(ret, template, 0, 0, tm1, tm2);
+ POSIX_RECORD_OPEN(ret, template, 0, tm1, tm2);
POSIX_POST_RECORD();
return(ret);
@@ -575,7 +512,7 @@ int DARSHAN_DECL(mkstemps)(char* template, int suffixlen)
tm2 = darshan_core_wtime();
POSIX_PRE_RECORD();
- POSIX_RECORD_OPEN(ret, template, 0, 0, tm1, tm2);
+ POSIX_RECORD_OPEN(ret, template, 0, tm1, tm2);
POSIX_POST_RECORD();
return(ret);
@@ -593,7 +530,7 @@ int DARSHAN_DECL(mkostemps)(char* template, int suffixlen, int flags)
tm2 = darshan_core_wtime();
POSIX_PRE_RECORD();
- POSIX_RECORD_OPEN(ret, template, 0, 0, tm1, tm2);
+ POSIX_RECORD_OPEN(ret, template, 0, tm1, tm2);
POSIX_POST_RECORD();
return(ret);
@@ -614,7 +551,7 @@ ssize_t DARSHAN_DECL(read)(int fd, void *buf, size_t count)
tm2 = darshan_core_wtime();
POSIX_PRE_RECORD();
- POSIX_RECORD_READ(ret, fd, 0, 0, aligned_flag, 0, tm1, tm2);
+ POSIX_RECORD_READ(ret, fd, 0, 0, aligned_flag, tm1, tm2);
POSIX_POST_RECORD();
return(ret);
@@ -635,7 +572,7 @@ ssize_t DARSHAN_DECL(write)(int fd, const void *buf, size_t count)
tm2 = darshan_core_wtime();
POSIX_PRE_RECORD();
- POSIX_RECORD_WRITE(ret, fd, 0, 0, aligned_flag, 0, tm1, tm2);
+ POSIX_RECORD_WRITE(ret, fd, 0, 0, aligned_flag, tm1, tm2);
POSIX_POST_RECORD();
return(ret);
@@ -656,7 +593,7 @@ ssize_t DARSHAN_DECL(pread)(int fd, void *buf, size_t count, off_t offset)
tm2 = darshan_core_wtime();
POSIX_PRE_RECORD();
- POSIX_RECORD_READ(ret, fd, 1, offset, aligned_flag, 0, tm1, tm2);
+ POSIX_RECORD_READ(ret, fd, 1, offset, aligned_flag, tm1, tm2);
POSIX_POST_RECORD();
return(ret);
@@ -677,7 +614,7 @@ ssize_t DARSHAN_DECL(pwrite)(int fd, const void *buf, size_t count, off_t offset
tm2 = darshan_core_wtime();
POSIX_PRE_RECORD();
- POSIX_RECORD_WRITE(ret, fd, 1, offset, aligned_flag, 0, tm1, tm2);
+ POSIX_RECORD_WRITE(ret, fd, 1, offset, aligned_flag, tm1, tm2);
POSIX_POST_RECORD();
return(ret);
@@ -698,7 +635,7 @@ ssize_t DARSHAN_DECL(pread64)(int fd, void *buf, size_t count, off64_t offset)
tm2 = darshan_core_wtime();
POSIX_PRE_RECORD();
- POSIX_RECORD_READ(ret, fd, 1, offset, aligned_flag, 0, tm1, tm2);
+ POSIX_RECORD_READ(ret, fd, 1, offset, aligned_flag, tm1, tm2);
POSIX_POST_RECORD();
return(ret);
@@ -719,7 +656,7 @@ ssize_t DARSHAN_DECL(pwrite64)(int fd, const void *buf, size_t count, off64_t of
tm2 = darshan_core_wtime();
POSIX_PRE_RECORD();
- POSIX_RECORD_WRITE(ret, fd, 1, offset, aligned_flag, 0, tm1, tm2);
+ POSIX_RECORD_WRITE(ret, fd, 1, offset, aligned_flag, tm1, tm2);
POSIX_POST_RECORD();
return(ret);
@@ -745,7 +682,7 @@ ssize_t DARSHAN_DECL(readv)(int fd, const struct iovec *iov, int iovcnt)
tm2 = darshan_core_wtime();
POSIX_PRE_RECORD();
- POSIX_RECORD_READ(ret, fd, 0, 0, aligned_flag, 0, tm1, tm2);
+ POSIX_RECORD_READ(ret, fd, 0, 0, aligned_flag, tm1, tm2);
POSIX_POST_RECORD();
return(ret);
@@ -771,67 +708,7 @@ ssize_t DARSHAN_DECL(writev)(int fd, const struct iovec *iov, int iovcnt)
tm2 = darshan_core_wtime();
POSIX_PRE_RECORD();
- POSIX_RECORD_WRITE(ret, fd, 0, 0, aligned_flag, 0, tm1, tm2);
- POSIX_POST_RECORD();
-
- return(ret);
-}
-
-size_t DARSHAN_DECL(fread)(void *ptr, size_t size, size_t nmemb, FILE *stream)
-{
- size_t ret;
- int aligned_flag = 0;
- int fd;
- double tm1, tm2;
-
- MAP_OR_FAIL(fread);
-
- if((unsigned long)ptr % darshan_mem_alignment == 0) aligned_flag = 1;
-
- tm1 = darshan_core_wtime();
- ret = __real_fread(ptr, size, nmemb, stream);
- tm2 = darshan_core_wtime();
-
- fd = fileno(stream);
- POSIX_PRE_RECORD();
- if(ret > 0)
- {
- POSIX_RECORD_READ(size*ret, fd, 0, 0, aligned_flag, 1, tm1, tm2);
- }
- else
- {
- POSIX_RECORD_READ(ret, fd, 0, 0, aligned_flag, 1, tm1, tm2);
- }
- POSIX_POST_RECORD();
-
- return(ret);
-}
-
-size_t DARSHAN_DECL(fwrite)(const void *ptr, size_t size, size_t nmemb, FILE *stream)
-{
- size_t ret;
- int aligned_flag = 0;
- int fd;
- double tm1, tm2;
-
- MAP_OR_FAIL(fwrite);
-
- if((unsigned long)ptr % darshan_mem_alignment == 0) aligned_flag = 1;
-
- tm1 = darshan_core_wtime();
- ret = __real_fwrite(ptr, size, nmemb, stream);
- tm2 = darshan_core_wtime();
-
- fd = fileno(stream);
- POSIX_PRE_RECORD();
- if(ret > 0)
- {
- POSIX_RECORD_WRITE(size*ret, fd, 0, 0, aligned_flag, 1, tm1, tm2);
- }
- else
- {
- POSIX_RECORD_WRITE(ret, fd, 0, 0, aligned_flag, 1, tm1, tm2);
- }
+ POSIX_RECORD_WRITE(ret, fd, 0, 0, aligned_flag, tm1, tm2);
POSIX_POST_RECORD();
return(ret);
@@ -897,38 +774,6 @@ off_t DARSHAN_DECL(lseek64)(int fd, off_t offset, int whence)
return(ret);
}
-int DARSHAN_DECL(fseek)(FILE *stream, long offset, int whence)
-{
- int ret;
- struct posix_file_record_ref *rec_ref;
- int fd;
- double tm1, tm2;
-
- MAP_OR_FAIL(fseek);
-
- tm1 = darshan_core_wtime();
- ret = __real_fseek(stream, offset, whence);
- tm2 = darshan_core_wtime();
-
- if(ret >= 0)
- {
- POSIX_PRE_RECORD();
- fd = fileno(stream);
- rec_ref = darshan_lookup_record_ref(posix_runtime->fd_hash, &fd, sizeof(int));
- if(rec_ref)
- {
- rec_ref->offset = ftell(stream);
- DARSHAN_TIMER_INC_NO_OVERLAP(
- rec_ref->file_rec->fcounters[POSIX_F_META_TIME],
- tm1, tm2, rec_ref->last_meta_end);
- rec_ref->file_rec->counters[POSIX_FSEEKS] += 1;
- }
- POSIX_POST_RECORD();
- }
-
- return(ret);
-}
-
int DARSHAN_DECL(__xstat)(int vers, const char *path, struct stat *buf)
{
int ret;
@@ -1199,37 +1044,6 @@ int DARSHAN_DECL(close)(int fd)
return(ret);
}
-int DARSHAN_DECL(fclose)(FILE *fp)
-{
- int ret;
- struct posix_file_record_ref *rec_ref;
- int fd = fileno(fp);
- double tm1, tm2;
-
- MAP_OR_FAIL(fclose);
-
- tm1 = darshan_core_wtime();
- ret = __real_fclose(fp);
- tm2 = darshan_core_wtime();
-
- POSIX_PRE_RECORD();
- rec_ref = darshan_lookup_record_ref(posix_runtime->fd_hash, &fd, sizeof(int));
- if(rec_ref)
- {
- rec_ref->last_byte_written = 0;
- rec_ref->last_byte_read = 0;
- rec_ref->file_rec->fcounters[POSIX_F_CLOSE_TIMESTAMP] =
- darshan_core_wtime();
- DARSHAN_TIMER_INC_NO_OVERLAP(
- rec_ref->file_rec->fcounters[POSIX_F_META_TIME],
- tm1, tm2, rec_ref->last_meta_end);
- darshan_delete_record_ref(&(posix_runtime->fd_hash), &fd, sizeof(int));
- }
- POSIX_POST_RECORD();
-
- return(ret);
-}
-
int DARSHAN_DECL(aio_read)(struct aiocb *aiocbp)
{
int ret;
@@ -1319,13 +1133,13 @@ ssize_t DARSHAN_DECL(aio_return)(struct aiocb *aiocbp)
if(aiocbp->aio_lio_opcode == LIO_WRITE)
{
POSIX_RECORD_WRITE(ret, aiocbp->aio_fildes,
- 1, aiocbp->aio_offset, aligned_flag, 0,
+ 1, aiocbp->aio_offset, aligned_flag,
tmp->tm1, tm2);
}
else if(aiocbp->aio_lio_opcode == LIO_READ)
{
POSIX_RECORD_READ(ret, aiocbp->aio_fildes,
- 1, aiocbp->aio_offset, aligned_flag, 0,
+ 1, aiocbp->aio_offset, aligned_flag,
tmp->tm1, tm2);
}
free(tmp);
@@ -1356,13 +1170,13 @@ ssize_t DARSHAN_DECL(aio_return64)(struct aiocb64 *aiocbp)
if(aiocbp->aio_lio_opcode == LIO_WRITE)
{
POSIX_RECORD_WRITE(ret, aiocbp->aio_fildes,
- 1, aiocbp->aio_offset, aligned_flag, 0,
+ 1, aiocbp->aio_offset, aligned_flag,
tmp->tm1, tm2);
}
else if(aiocbp->aio_lio_opcode == LIO_READ)
{
POSIX_RECORD_READ(ret, aiocbp->aio_fildes,
- 1, aiocbp->aio_offset, aligned_flag, 0,
+ 1, aiocbp->aio_offset, aligned_flag,
tmp->tm1, tm2);
}
free(tmp);
@@ -1927,15 +1741,15 @@ void darshan_posix_shutdown_bench_setup(int test_case)
case 1: /* single file-per-process */
snprintf(filepath, 256, "fpp-0_rank-%d", my_rank);
- POSIX_RECORD_OPEN(fd_array[0], filepath, 777, 0, 0, 1);
- POSIX_RECORD_WRITE(size_array[0], fd_array[0], 0, 0, 1, 0, 1, 2);
+ POSIX_RECORD_OPEN(fd_array[0], filepath, 777, 0, 1);
+ POSIX_RECORD_WRITE(size_array[0], fd_array[0], 0, 0, 1, 1, 2);
break;
case 2: /* single shared file */
snprintf(filepath, 256, "shared-0");
- POSIX_RECORD_OPEN(fd_array[0], filepath, 777, 0, 0, 1);
- POSIX_RECORD_WRITE(size_array[0], fd_array[0], 0, 0, 1, 0, 1, 2);
+ POSIX_RECORD_OPEN(fd_array[0], filepath, 777, 0, 1);
+ POSIX_RECORD_WRITE(size_array[0], fd_array[0], 0, 0, 1, 1, 2);
break;
case 3: /* 1024 unique files per proc */
@@ -1943,9 +1757,9 @@ void darshan_posix_shutdown_bench_setup(int test_case)
{
snprintf(filepath, 256, "fpp-%d_rank-%d", i , my_rank);
- POSIX_RECORD_OPEN(fd_array[i], filepath, 777, 0, 0, 1);
+ POSIX_RECORD_OPEN(fd_array[i], filepath, 777, 0, 1);
POSIX_RECORD_WRITE(size_array[i % DARSHAN_COMMON_VAL_MAX_RUNTIME_COUNT],
- fd_array[i], 0, 0, 1, 0, 1, 2);
+ fd_array[i], 0, 0, 1, 1, 2);
}
break;
@@ -1954,9 +1768,9 @@ void darshan_posix_shutdown_bench_setup(int test_case)
{
snprintf(filepath, 256, "shared-%d", i);
- POSIX_RECORD_OPEN(fd_array[i], filepath, 777, 0, 0, 1);
+ POSIX_RECORD_OPEN(fd_array[i], filepath, 777, 0, 1);
POSIX_RECORD_WRITE(size_array[i % DARSHAN_COMMON_VAL_MAX_RUNTIME_COUNT],
- fd_array[i], 0, 0, 1, 0, 1, 2);
+ fd_array[i], 0, 0, 1, 1, 2);
}
break;
=====================================
darshan-runtime/lib/darshan-stdio.c
=====================================
--- /dev/null
+++ b/darshan-runtime/lib/darshan-stdio.c
@@ -0,0 +1,1185 @@
+/*
+ * Copyright (C) 2015 University of Chicago.
+ * See COPYRIGHT notice in top-level directory.
+ *
+ */
+
+/* TODO list (general) for this module:
+ * - add stdio page to darshan-job-summary
+ * - update darshan-parser to include stdio information in any relevant
+ * performance estimate / summary modes
+ * - figure out what to do about posix module compatibility
+ * - remove stdio counters in POSIX or keep and set to -1?
+ * - affected counters in posix module:
+ * - POSIX_FOPENS
+ * - POSIX_FREADS
+ * - POSIX_FWRITES
+ * - POSIX_FSEEKS
+ */
+
+/* catalog of stdio functions instrumented by this module
+ *
+ * functions for opening streams
+ * --------------
+ * FILE *fdopen(int, const char *); DONE
+ * FILE *fopen(const char *, const char *); DONE
+ * FILE *fopen64(const char *, const char *); DONE
+ * FILE *freopen(const char *, const char *, FILE *); DONE
+ * FILE *freopen64(const char *, const char *, FILE *); DONE
+ *
+ * functions for closing streams
+ * --------------
+ * int fclose(FILE *); DONE
+ *
+ * functions for flushing streams
+ * --------------
+ * int fflush(FILE *); DONE
+ *
+ * functions for reading data
+ * --------------
+ * int fgetc(FILE *); DONE
+ * char *fgets(char *, int, FILE *); DONE
+ * size_t fread(void *, size_t, size_t, FILE *); DONE
+ * int fscanf(FILE *, const char *, ...); DONE
+ * int vfscanf(FILE *, const char *, va_list); DONE
+ * int getc(FILE *); DONE
+ * int getw(FILE *); DONE
+ *
+ * functions for writing data
+ * --------------
+ * int fprintf(FILE *, const char *, ...); DONE
+ * int vfprintf(FILE *, const char *, va_list); DONE
+ * int fputc(int, FILE *); DONE
+ * int fputs(const char *, FILE *); DONE
+ * size_t fwrite(const void *, size_t, size_t, FILE *); DONE
+ * int putc(int, FILE *); DONE
+ * int putw(int, FILE *); DONE
+ *
+ * functions for changing file position
+ * --------------
+ * int fseek(FILE *, long int, int); DONE
+ * int fseeko(FILE *, off_t, int); DONE
+ * int fseeko64(FILE *, off_t, int); DONE
+ * int fsetpos(FILE *, const fpos_t *); DONE
+ * int fsetpos64(FILE *, const fpos_t *); DONE
+ * void rewind(FILE *); DONE
+ *
+ * Omissions:
+ * - _unlocked() variants of the various flush, read, and write
+ * functions. There are many of these, but they are not available on all
+ * systems and the man page advises not to use them.
+ * - ungetc()
+ */
+
+#define _XOPEN_SOURCE 500
+#define _GNU_SOURCE
+
+#include "darshan-runtime-config.h"
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdarg.h>
+#include <string.h>
+#include <time.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <sys/uio.h>
+#include <sys/mman.h>
+#include <search.h>
+#include <assert.h>
+#include <libgen.h>
+#include <pthread.h>
+
+#include "darshan.h"
+#include "darshan-dynamic.h"
+
+DARSHAN_FORWARD_DECL(fopen, FILE*, (const char *path, const char *mode));
+DARSHAN_FORWARD_DECL(fopen64, FILE*, (const char *path, const char *mode));
+DARSHAN_FORWARD_DECL(fdopen, FILE*, (int fd, const char *mode));
+DARSHAN_FORWARD_DECL(freopen, FILE*, (const char *path, const char *mode, FILE *stream));
+DARSHAN_FORWARD_DECL(freopen64, FILE*, (const char *path, const char *mode, FILE *stream));
+DARSHAN_FORWARD_DECL(fclose, int, (FILE *fp));
+DARSHAN_FORWARD_DECL(fflush, int, (FILE *fp));
+DARSHAN_FORWARD_DECL(fwrite, size_t, (const void *ptr, size_t size, size_t nmemb, FILE *stream));
+DARSHAN_FORWARD_DECL(fputc, int, (int c, FILE *stream));
+DARSHAN_FORWARD_DECL(putw, int, (int w, FILE *stream));
+DARSHAN_FORWARD_DECL(fputs, int, (const char *s, FILE *stream));
+DARSHAN_FORWARD_DECL(fprintf, int, (FILE *stream, const char *format, ...));
+DARSHAN_FORWARD_DECL(vfprintf, int, (FILE *stream, const char *format, va_list));
+DARSHAN_FORWARD_DECL(fread, size_t, (void *ptr, size_t size, size_t nmemb, FILE *stream));
+DARSHAN_FORWARD_DECL(fgetc, int, (FILE *stream));
+DARSHAN_FORWARD_DECL(getw, int, (FILE *stream));
+DARSHAN_FORWARD_DECL(_IO_getc, int, (FILE *stream));
+DARSHAN_FORWARD_DECL(_IO_putc, int, (int, FILE *stream));
+DARSHAN_FORWARD_DECL(fscanf, int, (FILE *stream, const char *format, ...));
+DARSHAN_FORWARD_DECL(__isoc99_fscanf, int, (FILE *stream, const char *format, ...));
+DARSHAN_FORWARD_DECL(vfscanf, int, (FILE *stream, const char *format, va_list ap));
+DARSHAN_FORWARD_DECL(fgets, char*, (char *s, int size, FILE *stream));
+DARSHAN_FORWARD_DECL(fseek, int, (FILE *stream, long offset, int whence));
+DARSHAN_FORWARD_DECL(fseeko, int, (FILE *stream, off_t offset, int whence));
+DARSHAN_FORWARD_DECL(fseeko64, int, (FILE *stream, off_t offset, int whence));
+DARSHAN_FORWARD_DECL(fsetpos, int, (FILE *stream, const fpos_t *pos));
+DARSHAN_FORWARD_DECL(fsetpos64, int, (FILE *stream, const fpos64_t *pos));
+DARSHAN_FORWARD_DECL(rewind, void, (FILE *stream));
+
+/* structure to track stdio stats at runtime */
+struct stdio_file_record_ref
+{
+ struct darshan_stdio_file* file_rec;
+ int64_t offset;
+ double last_meta_end;
+ double last_read_end;
+ double last_write_end;
+};
+
+/* The stdio_runtime structure maintains necessary state for storing
+ * STDIO file records and for coordinating with darshan-core at
+ * shutdown time.
+ */
+struct stdio_runtime
+{
+ void *rec_id_hash;
+ void *stream_hash;
+ int file_rec_count;
+};
+
+static struct stdio_runtime *stdio_runtime = NULL;
+static pthread_mutex_t stdio_runtime_mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
+static int instrumentation_disabled = 0;
+static int darshan_mem_alignment = 1;
+static int my_rank = -1;
+
+static void stdio_runtime_initialize(void);
+static void stdio_shutdown(
+ MPI_Comm mod_comm,
+ darshan_record_id *shared_recs,
+ int shared_rec_count,
+ void **stdio_buf,
+ int *stdio_buf_sz);
+static void stdio_record_reduction_op(void* infile_v, void* inoutfile_v,
+ int *len, MPI_Datatype *datatype);
+static struct stdio_file_record_ref *stdio_track_new_file_record(
+ darshan_record_id rec_id, const char *path);
+static void stdio_cleanup_runtime();
+
+#define STDIO_LOCK() pthread_mutex_lock(&stdio_runtime_mutex)
+#define STDIO_UNLOCK() pthread_mutex_unlock(&stdio_runtime_mutex)
+
+#define STDIO_PRE_RECORD() do { \
+ STDIO_LOCK(); \
+ if(!stdio_runtime && !instrumentation_disabled) stdio_runtime_initialize(); \
+ if(!stdio_runtime) { \
+ STDIO_UNLOCK(); \
+ return(ret); \
+ } \
+} while(0)
+
+#define STDIO_POST_RECORD() do { \
+ STDIO_UNLOCK(); \
+} while(0)
+
+#define STDIO_RECORD_OPEN(__ret, __path, __tm1, __tm2) do { \
+ darshan_record_id rec_id; \
+ struct stdio_file_record_ref* rec_ref; \
+ char *newpath; \
+ if(__ret == NULL) break; \
+ newpath = darshan_clean_file_path(__path); \
+ if(!newpath) newpath = (char*)__path; \
+ if(darshan_core_excluded_path(newpath)) { \
+ if(newpath != (char*)__path) free(newpath); \
+ break; \
+ } \
+ rec_id = darshan_core_gen_record_id(newpath); \
+ rec_ref = darshan_lookup_record_ref(stdio_runtime->rec_id_hash, &rec_id, sizeof(rec_id)); \
+ if(!rec_ref) rec_ref = stdio_track_new_file_record(rec_id, newpath); \
+ if(!rec_ref) { \
+ if(newpath != (char*)__path) free(newpath); \
+ break; \
+ } \
+ rec_ref->offset = 0; \
+ rec_ref->file_rec->counters[STDIO_OPENS] += 1; \
+ if(rec_ref->file_rec->fcounters[STDIO_F_OPEN_START_TIMESTAMP] == 0 || \
+ rec_ref->file_rec->fcounters[STDIO_F_OPEN_START_TIMESTAMP] > __tm1) \
+ rec_ref->file_rec->fcounters[STDIO_F_OPEN_START_TIMESTAMP] = __tm1; \
+ rec_ref->file_rec->fcounters[STDIO_F_OPEN_END_TIMESTAMP] = __tm2; \
+ DARSHAN_TIMER_INC_NO_OVERLAP(rec_ref->file_rec->fcounters[STDIO_F_META_TIME], __tm1, __tm2, rec_ref->last_meta_end); \
+ darshan_add_record_ref(&(stdio_runtime->stream_hash), &(__ret), sizeof(__ret), rec_ref); \
+ if(newpath != (char*)__path) free(newpath); \
+} while(0)
+
+
+#define STDIO_RECORD_READ(__fp, __bytes, __tm1, __tm2) do{ \
+ struct stdio_file_record_ref* rec_ref; \
+ int64_t this_offset; \
+ rec_ref = darshan_lookup_record_ref(stdio_runtime->stream_hash, &(__fp), sizeof(__fp)); \
+ if(!rec_ref) break; \
+ this_offset = rec_ref->offset; \
+ rec_ref->offset = this_offset + __bytes; \
+ if(rec_ref->file_rec->counters[STDIO_MAX_BYTE_READ] < (this_offset + __bytes - 1)) \
+ rec_ref->file_rec->counters[STDIO_MAX_BYTE_READ] = (this_offset + __bytes - 1); \
+ rec_ref->file_rec->counters[STDIO_BYTES_READ] += __bytes; \
+ rec_ref->file_rec->counters[STDIO_READS] += 1; \
+ if(rec_ref->file_rec->fcounters[STDIO_F_READ_START_TIMESTAMP] == 0 || \
+ rec_ref->file_rec->fcounters[STDIO_F_READ_START_TIMESTAMP] > __tm1) \
+ rec_ref->file_rec->fcounters[STDIO_F_READ_START_TIMESTAMP] = __tm1; \
+ rec_ref->file_rec->fcounters[STDIO_F_READ_END_TIMESTAMP] = __tm2; \
+ DARSHAN_TIMER_INC_NO_OVERLAP(rec_ref->file_rec->fcounters[STDIO_F_READ_TIME], __tm1, __tm2, rec_ref->last_write_end); \
+} while(0)
+
+#define STDIO_RECORD_WRITE(__fp, __bytes, __tm1, __tm2, __fflush_flag) do{ \
+ struct stdio_file_record_ref* rec_ref; \
+ int64_t this_offset; \
+ rec_ref = darshan_lookup_record_ref(stdio_runtime->stream_hash, &(__fp), sizeof(__fp)); \
+ if(!rec_ref) break; \
+ this_offset = rec_ref->offset; \
+ rec_ref->offset = this_offset + __bytes; \
+ if(rec_ref->file_rec->counters[STDIO_MAX_BYTE_WRITTEN] < (this_offset + __bytes - 1)) \
+ rec_ref->file_rec->counters[STDIO_MAX_BYTE_WRITTEN] = (this_offset + __bytes - 1); \
+ rec_ref->file_rec->counters[STDIO_BYTES_WRITTEN] += __bytes; \
+ if(__fflush_flag) \
+ rec_ref->file_rec->counters[STDIO_FLUSHES] += 1; \
+ else \
+ rec_ref->file_rec->counters[STDIO_WRITES] += 1; \
+ if(rec_ref->file_rec->fcounters[STDIO_F_WRITE_START_TIMESTAMP] == 0 || \
+ rec_ref->file_rec->fcounters[STDIO_F_WRITE_START_TIMESTAMP] > __tm1) \
+ rec_ref->file_rec->fcounters[STDIO_F_WRITE_START_TIMESTAMP] = __tm1; \
+ rec_ref->file_rec->fcounters[STDIO_F_WRITE_END_TIMESTAMP] = __tm2; \
+ DARSHAN_TIMER_INC_NO_OVERLAP(rec_ref->file_rec->fcounters[STDIO_F_WRITE_TIME], __tm1, __tm2, rec_ref->last_write_end); \
+} while(0)
+
+FILE* DARSHAN_DECL(fopen)(const char *path, const char *mode)
+{
+ FILE* ret;
+ double tm1, tm2;
+
+ MAP_OR_FAIL(fopen);
+
+ tm1 = darshan_core_wtime();
+ ret = __real_fopen(path, mode);
+ tm2 = darshan_core_wtime();
+
+ STDIO_PRE_RECORD();
+ STDIO_RECORD_OPEN(ret, path, tm1, tm2);
+ STDIO_POST_RECORD();
+
+ return(ret);
+}
+
+FILE* DARSHAN_DECL(fopen64)(const char *path, const char *mode)
+{
+ FILE* ret;
+ double tm1, tm2;
+
+ MAP_OR_FAIL(fopen);
+
+ tm1 = darshan_core_wtime();
+ ret = __real_fopen64(path, mode);
+ tm2 = darshan_core_wtime();
+
+ STDIO_PRE_RECORD();
+ STDIO_RECORD_OPEN(ret, path, tm1, tm2);
+ STDIO_POST_RECORD();
+
+ return(ret);
+}
+
+FILE* DARSHAN_DECL(fdopen)(int fd, const char *mode)
+{
+ FILE* ret;
+ double tm1, tm2;
+
+ MAP_OR_FAIL(fdopen);
+
+ tm1 = darshan_core_wtime();
+ ret = __real_fdopen(fd, mode);
+ tm2 = darshan_core_wtime();
+
+ STDIO_PRE_RECORD();
+ STDIO_RECORD_OPEN(ret, "UNKNOWN-FDOPEN", tm1, tm2);
+ STDIO_POST_RECORD();
+
+ return(ret);
+}
+
+FILE* DARSHAN_DECL(freopen)(const char *path, const char *mode, FILE *stream)
+{
+ FILE* ret;
+ double tm1, tm2;
+
+ MAP_OR_FAIL(freopen);
+
+ tm1 = darshan_core_wtime();
+ ret = __real_freopen(path, mode, stream);
+ tm2 = darshan_core_wtime();
+
+ STDIO_PRE_RECORD();
+ STDIO_RECORD_OPEN(ret, path, tm1, tm2);
+ STDIO_POST_RECORD();
+
+ return(ret);
+}
+
+FILE* DARSHAN_DECL(freopen64)(const char *path, const char *mode, FILE *stream)
+{
+ FILE* ret;
+ double tm1, tm2;
+
+ MAP_OR_FAIL(freopen64);
+
+ tm1 = darshan_core_wtime();
+ ret = __real_freopen64(path, mode, stream);
+ tm2 = darshan_core_wtime();
+
+ STDIO_PRE_RECORD();
+ STDIO_RECORD_OPEN(ret, path, tm1, tm2);
+ STDIO_POST_RECORD();
+
+ return(ret);
+}
+
+
+int DARSHAN_DECL(fflush)(FILE *fp)
+{
+ double tm1, tm2;
+ int ret;
+
+ MAP_OR_FAIL(fflush);
+
+ tm1 = darshan_core_wtime();
+ ret = __real_fflush(fp);
+ tm2 = darshan_core_wtime();
+
+ STDIO_PRE_RECORD();
+ if(ret >= 0)
+ STDIO_RECORD_WRITE(fp, 0, tm1, tm2, 1);
+ STDIO_POST_RECORD();
+
+ return(ret);
+}
+
+int DARSHAN_DECL(fclose)(FILE *fp)
+{
+ double tm1, tm2;
+ int ret;
+ struct stdio_file_record_ref *rec_ref;
+
+ MAP_OR_FAIL(fclose);
+
+ tm1 = darshan_core_wtime();
+ ret = __real_fclose(fp);
+ tm2 = darshan_core_wtime();
+
+ STDIO_PRE_RECORD();
+ rec_ref = darshan_lookup_record_ref(stdio_runtime->stream_hash, &fp, sizeof(fp));
+ if(rec_ref)
+ {
+ if(rec_ref->file_rec->fcounters[STDIO_F_CLOSE_START_TIMESTAMP] == 0 ||
+ rec_ref->file_rec->fcounters[STDIO_F_CLOSE_START_TIMESTAMP] > tm1)
+ rec_ref->file_rec->fcounters[STDIO_F_CLOSE_START_TIMESTAMP] = tm1;
+ rec_ref->file_rec->fcounters[STDIO_F_CLOSE_END_TIMESTAMP] = tm2;
+ DARSHAN_TIMER_INC_NO_OVERLAP(
+ rec_ref->file_rec->fcounters[STDIO_F_META_TIME],
+ tm1, tm2, rec_ref->last_meta_end);
+ darshan_delete_record_ref(&(stdio_runtime->stream_hash), &fp, sizeof(fp));
+ }
+ STDIO_POST_RECORD();
+
+ return(ret);
+}
+
+size_t DARSHAN_DECL(fwrite)(const void *ptr, size_t size, size_t nmemb, FILE *stream)
+{
+ size_t ret;
+ double tm1, tm2;
+
+ MAP_OR_FAIL(fwrite);
+
+ tm1 = darshan_core_wtime();
+ ret = __real_fwrite(ptr, size, nmemb, stream);
+ tm2 = darshan_core_wtime();
+
+ STDIO_PRE_RECORD();
+ if(ret > 0)
+ STDIO_RECORD_WRITE(stream, size*ret, tm1, tm2, 0);
+ STDIO_POST_RECORD();
+
+ return(ret);
+}
+
+
+int DARSHAN_DECL(fputc)(int c, FILE *stream)
+{
+ int ret;
+ double tm1, tm2;
+
+ MAP_OR_FAIL(fputc);
+
+ tm1 = darshan_core_wtime();
+ ret = __real_fputc(c, stream);
+ tm2 = darshan_core_wtime();
+
+ STDIO_PRE_RECORD();
+ if(ret != EOF)
+ STDIO_RECORD_WRITE(stream, 1, tm1, tm2, 0);
+ STDIO_POST_RECORD();
+
+ return(ret);
+}
+
+int DARSHAN_DECL(putw)(int w, FILE *stream)
+{
+ int ret;
+ double tm1, tm2;
+
+ MAP_OR_FAIL(putw);
+
+ tm1 = darshan_core_wtime();
+ ret = __real_putw(w, stream);
+ tm2 = darshan_core_wtime();
+
+ STDIO_PRE_RECORD();
+ if(ret != EOF)
+ STDIO_RECORD_WRITE(stream, sizeof(int), tm1, tm2, 0);
+ STDIO_POST_RECORD();
+
+ return(ret);
+}
+
+
+
+int DARSHAN_DECL(fputs)(const char *s, FILE *stream)
+{
+ int ret;
+ double tm1, tm2;
+
+ MAP_OR_FAIL(fputs);
+
+ tm1 = darshan_core_wtime();
+ ret = __real_fputs(s, stream);
+ tm2 = darshan_core_wtime();
+
+ STDIO_PRE_RECORD();
+ if(ret != EOF && ret > 0)
+ STDIO_RECORD_WRITE(stream, strlen(s), tm1, tm2, 0);
+ STDIO_POST_RECORD();
+
+ return(ret);
+}
+
+int DARSHAN_DECL(vfprintf)(FILE *stream, const char *format, va_list ap)
+{
+ int ret;
+ double tm1, tm2;
+ long start_off, end_off;
+
+ MAP_OR_FAIL(vfprintf);
+
+ tm1 = darshan_core_wtime();
+ start_off = ftell(stream);
+ ret = __real_vfprintf(stream, format, ap);
+ end_off = ftell(stream);
+ tm2 = darshan_core_wtime();
+
+ STDIO_PRE_RECORD();
+ if(ret > 0)
+ STDIO_RECORD_WRITE(stream, (end_off-start_off), tm1, tm2, 0);
+ STDIO_POST_RECORD();
+
+ return(ret);
+}
+
+
+int DARSHAN_DECL(fprintf)(FILE *stream, const char *format, ...)
+{
+ int ret;
+ double tm1, tm2;
+ va_list ap;
+ long start_off, end_off;
+
+ MAP_OR_FAIL(vfprintf);
+
+ tm1 = darshan_core_wtime();
+ /* NOTE: we intentionally switch to vfprintf here to handle the variable
+ * length arguments.
+ */
+ start_off = ftell(stream);
+ va_start(ap, format);
+ ret = __real_vfprintf(stream, format, ap);
+ va_end(ap);
+ end_off = ftell(stream);
+ tm2 = darshan_core_wtime();
+
+ STDIO_PRE_RECORD();
+ if(ret > 0)
+ STDIO_RECORD_WRITE(stream, (end_off-start_off), tm1, tm2, 0);
+ STDIO_POST_RECORD();
+
+ return(ret);
+}
+
+size_t DARSHAN_DECL(fread)(void *ptr, size_t size, size_t nmemb, FILE *stream)
+{
+ size_t ret;
+ double tm1, tm2;
+
+ MAP_OR_FAIL(fread);
+
+ tm1 = darshan_core_wtime();
+ ret = __real_fread(ptr, size, nmemb, stream);
+ tm2 = darshan_core_wtime();
+
+ STDIO_PRE_RECORD();
+ if(ret > 0)
+ STDIO_RECORD_READ(stream, size*ret, tm1, tm2);
+ STDIO_POST_RECORD();
+
+ return(ret);
+}
+
+int DARSHAN_DECL(fgetc)(FILE *stream)
+{
+ int ret;
+ double tm1, tm2;
+
+ MAP_OR_FAIL(fgetc);
+
+ tm1 = darshan_core_wtime();
+ ret = __real_fgetc(stream);
+ tm2 = darshan_core_wtime();
+
+ STDIO_PRE_RECORD();
+ if(ret != EOF)
+ STDIO_RECORD_READ(stream, 1, tm1, tm2);
+ STDIO_POST_RECORD();
+
+ return(ret);
+}
+
+/* NOTE: stdio.h typically implements getc() as a macro pointing to _IO_getc */
+int DARSHAN_DECL(_IO_getc)(FILE *stream)
+{
+ int ret;
+ double tm1, tm2;
+
+ MAP_OR_FAIL(_IO_getc);
+
+ tm1 = darshan_core_wtime();
+ ret = __real__IO_getc(stream);
+ tm2 = darshan_core_wtime();
+
+ STDIO_PRE_RECORD();
+ if(ret != EOF)
+ STDIO_RECORD_READ(stream, 1, tm1, tm2);
+ STDIO_POST_RECORD();
+
+ return(ret);
+}
+
+/* NOTE: stdio.h typically implements putc() as a macro pointing to _IO_putc */
+int DARSHAN_DECL(_IO_putc)(int c, FILE *stream)
+{
+ int ret;
+ double tm1, tm2;
+
+ MAP_OR_FAIL(_IO_putc);
+
+ tm1 = darshan_core_wtime();
+ ret = __real__IO_putc(c, stream);
+ tm2 = darshan_core_wtime();
+
+ STDIO_PRE_RECORD();
+ if(ret != EOF)
+ STDIO_RECORD_WRITE(stream, 1, tm1, tm2, 0);
+ STDIO_POST_RECORD();
+
+ return(ret);
+}
+
+int DARSHAN_DECL(getw)(FILE *stream)
+{
+ int ret;
+ double tm1, tm2;
+
+ MAP_OR_FAIL(getw);
+
+ tm1 = darshan_core_wtime();
+ ret = __real_getw(stream);
+ tm2 = darshan_core_wtime();
+
+ STDIO_PRE_RECORD();
+ if(ret != EOF || ferror(stream) == 0)
+ STDIO_RECORD_READ(stream, sizeof(int), tm1, tm2);
+ STDIO_POST_RECORD();
+
+ return(ret);
+}
+
+/* NOTE: some glibc versions use __isoc99_fscanf as the underlying symbol
+ * rather than fscanf
+ */
+int DARSHAN_DECL(__isoc99_fscanf)(FILE *stream, const char *format, ...)
+{
+ int ret;
+ double tm1, tm2;
+ va_list ap;
+ long start_off, end_off;
+
+ MAP_OR_FAIL(vfscanf);
+
+ tm1 = darshan_core_wtime();
+ /* NOTE: we intentionally switch to vfscanf here to handle the variable
+ * length arguments.
+ */
+ start_off = ftell(stream);
+ va_start(ap, format);
+ ret = __real_vfscanf(stream, format, ap);
+ va_end(ap);
+ end_off = ftell(stream);
+ tm2 = darshan_core_wtime();
+
+ STDIO_PRE_RECORD();
+ if(ret != 0)
+ STDIO_RECORD_READ(stream, (end_off-start_off), tm1, tm2);
+ STDIO_POST_RECORD();
+
+ return(ret);
+}
+
+
+int DARSHAN_DECL(fscanf)(FILE *stream, const char *format, ...)
+{
+ int ret;
+ double tm1, tm2;
+ va_list ap;
+ long start_off, end_off;
+
+ MAP_OR_FAIL(vfscanf);
+
+ tm1 = darshan_core_wtime();
+ /* NOTE: we intentionally switch to vfscanf here to handle the variable
+ * length arguments.
+ */
+ start_off = ftell(stream);
+ va_start(ap, format);
+ ret = __real_vfscanf(stream, format, ap);
+ va_end(ap);
+ end_off = ftell(stream);
+ tm2 = darshan_core_wtime();
+
+ STDIO_PRE_RECORD();
+ if(ret != 0)
+ STDIO_RECORD_READ(stream, (end_off-start_off), tm1, tm2);
+ STDIO_POST_RECORD();
+
+ return(ret);
+}
+
+int DARSHAN_DECL(vfscanf)(FILE *stream, const char *format, va_list ap)
+{
+ int ret;
+ double tm1, tm2;
+ long start_off, end_off;
+
+ MAP_OR_FAIL(vfscanf);
+
+ tm1 = darshan_core_wtime();
+ start_off = ftell(stream);
+ ret = __real_vfscanf(stream, format, ap);
+ end_off = ftell(stream);
+ tm2 = darshan_core_wtime();
+
+ STDIO_PRE_RECORD();
+ if(ret != 0)
+ STDIO_RECORD_READ(stream, end_off-start_off, tm1, tm2);
+ STDIO_POST_RECORD();
+
+ return(ret);
+}
+
+
+char* DARSHAN_DECL(fgets)(char *s, int size, FILE *stream)
+{
+ char *ret;
+ double tm1, tm2;
+
+ MAP_OR_FAIL(fgets);
+
+ tm1 = darshan_core_wtime();
+ ret = __real_fgets(s, size, stream);
+ tm2 = darshan_core_wtime();
+
+ STDIO_PRE_RECORD();
+ if(ret != NULL)
+ STDIO_RECORD_READ(stream, strlen(ret), tm1, tm2);
+ STDIO_POST_RECORD();
+
+ return(ret);
+}
+
+
+void DARSHAN_DECL(rewind)(FILE *stream)
+{
+ double tm1, tm2;
+ struct stdio_file_record_ref *rec_ref;
+
+ MAP_OR_FAIL(rewind);
+
+ tm1 = darshan_core_wtime();
+ __real_rewind(stream);
+ tm2 = darshan_core_wtime();
+
+ /* NOTE: we don't use STDIO_PRE_RECORD here because there is no return
+ * value in this wrapper.
+ */
+ STDIO_LOCK();
+ if(!stdio_runtime && !instrumentation_disabled) stdio_runtime_initialize();
+ if(!stdio_runtime) {
+ STDIO_UNLOCK();
+ return;
+ }
+
+ rec_ref = darshan_lookup_record_ref(stdio_runtime->stream_hash, &stream, sizeof(stream));
+
+ if(rec_ref)
+ {
+ rec_ref->offset = 0;
+ DARSHAN_TIMER_INC_NO_OVERLAP(
+ rec_ref->file_rec->fcounters[STDIO_F_META_TIME],
+ tm1, tm2, rec_ref->last_meta_end);
+ rec_ref->file_rec->counters[STDIO_SEEKS] += 1;
+ }
+ STDIO_POST_RECORD();
+
+ return;
+}
+
+int DARSHAN_DECL(fseek)(FILE *stream, long offset, int whence)
+{
+ int ret;
+ struct stdio_file_record_ref *rec_ref;
+ double tm1, tm2;
+
+ MAP_OR_FAIL(fseek);
+
+ tm1 = darshan_core_wtime();
+ ret = __real_fseek(stream, offset, whence);
+ tm2 = darshan_core_wtime();
+
+ if(ret >= 0)
+ {
+ STDIO_PRE_RECORD();
+ rec_ref = darshan_lookup_record_ref(stdio_runtime->stream_hash, &stream, sizeof(stream));
+ if(rec_ref)
+ {
+ rec_ref->offset = ftell(stream);
+ DARSHAN_TIMER_INC_NO_OVERLAP(
+ rec_ref->file_rec->fcounters[STDIO_F_META_TIME],
+ tm1, tm2, rec_ref->last_meta_end);
+ rec_ref->file_rec->counters[STDIO_SEEKS] += 1;
+ }
+ STDIO_POST_RECORD();
+ }
+
+ return(ret);
+}
+
+int DARSHAN_DECL(fseeko)(FILE *stream, off_t offset, int whence)
+{
+ int ret;
+ struct stdio_file_record_ref *rec_ref;
+ double tm1, tm2;
+
+ MAP_OR_FAIL(fseeko);
+
+ tm1 = darshan_core_wtime();
+ ret = __real_fseeko(stream, offset, whence);
+ tm2 = darshan_core_wtime();
+
+ if(ret >= 0)
+ {
+ STDIO_PRE_RECORD();
+ rec_ref = darshan_lookup_record_ref(stdio_runtime->stream_hash, &stream, sizeof(stream));
+ if(rec_ref)
+ {
+ rec_ref->offset = ftell(stream);
+ DARSHAN_TIMER_INC_NO_OVERLAP(
+ rec_ref->file_rec->fcounters[STDIO_F_META_TIME],
+ tm1, tm2, rec_ref->last_meta_end);
+ rec_ref->file_rec->counters[STDIO_SEEKS] += 1;
+ }
+ STDIO_POST_RECORD();
+ }
+
+ return(ret);
+}
+
+int DARSHAN_DECL(fseeko64)(FILE *stream, off_t offset, int whence)
+{
+ int ret;
+ struct stdio_file_record_ref *rec_ref;
+ double tm1, tm2;
+
+ MAP_OR_FAIL(fseeko64);
+
+ tm1 = darshan_core_wtime();
+ ret = __real_fseeko64(stream, offset, whence);
+ tm2 = darshan_core_wtime();
+
+ if(ret >= 0)
+ {
+ STDIO_PRE_RECORD();
+ rec_ref = darshan_lookup_record_ref(stdio_runtime->stream_hash, &stream, sizeof(stream));
+ if(rec_ref)
+ {
+ rec_ref->offset = ftell(stream);
+ DARSHAN_TIMER_INC_NO_OVERLAP(
+ rec_ref->file_rec->fcounters[STDIO_F_META_TIME],
+ tm1, tm2, rec_ref->last_meta_end);
+ rec_ref->file_rec->counters[STDIO_SEEKS] += 1;
+ }
+ STDIO_POST_RECORD();
+ }
+
+ return(ret);
+}
+
+int DARSHAN_DECL(fsetpos)(FILE *stream, const fpos_t *pos)
+{
+ int ret;
+ struct stdio_file_record_ref *rec_ref;
+ double tm1, tm2;
+
+ MAP_OR_FAIL(fsetpos);
+
+ tm1 = darshan_core_wtime();
+ ret = __real_fsetpos(stream, pos);
+ tm2 = darshan_core_wtime();
+
+ if(ret >= 0)
+ {
+ STDIO_PRE_RECORD();
+ rec_ref = darshan_lookup_record_ref(stdio_runtime->stream_hash, &stream, sizeof(stream));
+ if(rec_ref)
+ {
+ rec_ref->offset = ftell(stream);
+ DARSHAN_TIMER_INC_NO_OVERLAP(
+ rec_ref->file_rec->fcounters[STDIO_F_META_TIME],
+ tm1, tm2, rec_ref->last_meta_end);
+ rec_ref->file_rec->counters[STDIO_SEEKS] += 1;
+ }
+ STDIO_POST_RECORD();
+ }
+
+ return(ret);
+}
+
+int DARSHAN_DECL(fsetpos64)(FILE *stream, const fpos64_t *pos)
+{
+ int ret;
+ struct stdio_file_record_ref *rec_ref;
+ double tm1, tm2;
+
+ MAP_OR_FAIL(fsetpos64);
+
+ tm1 = darshan_core_wtime();
+ ret = __real_fsetpos64(stream, pos);
+ tm2 = darshan_core_wtime();
+
+ if(ret >= 0)
+ {
+ STDIO_PRE_RECORD();
+ rec_ref = darshan_lookup_record_ref(stdio_runtime->stream_hash, &stream, sizeof(stream));
+ if(rec_ref)
+ {
+ rec_ref->offset = ftell(stream);
+ DARSHAN_TIMER_INC_NO_OVERLAP(
+ rec_ref->file_rec->fcounters[STDIO_F_META_TIME],
+ tm1, tm2, rec_ref->last_meta_end);
+ rec_ref->file_rec->counters[STDIO_SEEKS] += 1;
+ }
+ STDIO_POST_RECORD();
+ }
+
+ return(ret);
+}
+
+
+/**********************************************************
+ * Internal functions for manipulating STDIO module state *
+ **********************************************************/
+
+/* initialize internal STDIO module data structures and register with darshan-core */
+static void stdio_runtime_initialize()
+{
+ int stdio_buf_size;
+
+ /* try to store default number of records for this module */
+ stdio_buf_size = DARSHAN_DEF_MOD_REC_COUNT * sizeof(struct darshan_stdio_file);
+
+ /* don't do anything if already initialized or instrumenation is disabled */
+ if(stdio_runtime || instrumentation_disabled)
+ return;
+
+ /* register the stdio module with darshan core */
+ darshan_core_register_module(
+ DARSHAN_STDIO_MOD,
+ &stdio_shutdown,
+ &stdio_buf_size,
+ &my_rank,
+ &darshan_mem_alignment);
+
+ /* return if darshan-core does not provide enough module memory */
+ if(stdio_buf_size < sizeof(struct darshan_stdio_file))
+ {
+ darshan_core_unregister_module(DARSHAN_POSIX_MOD);
+ return;
+ }
+
+ stdio_runtime = malloc(sizeof(*stdio_runtime));
+ if(!stdio_runtime)
+ {
+ darshan_core_unregister_module(DARSHAN_STDIO_MOD);
+ return;
+ }
+ memset(stdio_runtime, 0, sizeof(*stdio_runtime));
+}
+
+/************************************************************************
+ * Functions exported by this module for coordinating with darshan-core *
+ ************************************************************************/
+
+static void stdio_record_reduction_op(void* infile_v, void* inoutfile_v,
+ int *len, MPI_Datatype *datatype)
+{
+ struct darshan_stdio_file tmp_file;
+ struct darshan_stdio_file *infile = infile_v;
+ struct darshan_stdio_file *inoutfile = inoutfile_v;
+ int i, j;
+
+ assert(stdio_runtime);
+
+ for(i=0; i<*len; i++)
+ {
+ memset(&tmp_file, 0, sizeof(struct darshan_stdio_file));
+ tmp_file.base_rec.id = infile->base_rec.id;
+ tmp_file.base_rec.rank = -1;
+
+ /* sum */
+ for(j=STDIO_OPENS; j<=STDIO_BYTES_READ; j++)
+ {
+ tmp_file.counters[j] = infile->counters[j] + inoutfile->counters[j];
+ }
+
+ /* max */
+ for(j=STDIO_MAX_BYTE_READ; j<=STDIO_MAX_BYTE_WRITTEN; j++)
+ {
+ if(infile->counters[j] > inoutfile->counters[j])
+ tmp_file.counters[j] = infile->counters[j];
+ else
+ tmp_file.counters[j] = inoutfile->counters[j];
+ }
+
+ /* sum */
+ for(j=STDIO_F_META_TIME; j<=STDIO_F_READ_TIME; j++)
+ {
+ tmp_file.fcounters[j] = infile->fcounters[j] + inoutfile->fcounters[j];
+ }
+
+ /* min non-zero (if available) value */
+ for(j=STDIO_F_OPEN_START_TIMESTAMP; j<=STDIO_F_READ_START_TIMESTAMP; j++)
+ {
+ if((infile->fcounters[j] < inoutfile->fcounters[j] &&
+ infile->fcounters[j] > 0) || inoutfile->fcounters[j] == 0)
+ tmp_file.fcounters[j] = infile->fcounters[j];
+ else
+ tmp_file.fcounters[j] = inoutfile->fcounters[j];
+ }
+
+ /* max */
+ for(j=STDIO_F_OPEN_END_TIMESTAMP; j<=STDIO_F_READ_END_TIMESTAMP; j++)
+ {
+ if(infile->fcounters[j] > inoutfile->fcounters[j])
+ tmp_file.fcounters[j] = infile->fcounters[j];
+ else
+ tmp_file.fcounters[j] = inoutfile->fcounters[j];
+ }
+
+ /* update pointers */
+ *inoutfile = tmp_file;
+ inoutfile++;
+ infile++;
+ }
+
+ return;
+}
+
+static void stdio_shutdown(
+ MPI_Comm mod_comm,
+ darshan_record_id *shared_recs,
+ int shared_rec_count,
+ void **stdio_buf,
+ int *stdio_buf_sz)
+{
+ struct stdio_file_record_ref *rec_ref;
+ struct darshan_stdio_file *stdio_rec_buf = *(struct darshan_stdio_file **)stdio_buf;
+ int i;
+ struct darshan_stdio_file *red_send_buf = NULL;
+ struct darshan_stdio_file *red_recv_buf = NULL;
+ MPI_Datatype red_type;
+ MPI_Op red_op;
+ int stdio_rec_count;
+
+ STDIO_LOCK();
+ assert(stdio_runtime);
+ stdio_rec_count = stdio_runtime->file_rec_count;
+
+ /* if there are globally shared files, do a shared file reduction */
+ /* NOTE: the shared file reduction is also skipped if the
+ * DARSHAN_DISABLE_SHARED_REDUCTION environment variable is set.
+ */
+ if(shared_rec_count && !getenv("DARSHAN_DISABLE_SHARED_REDUCTION"))
+ {
+ /* necessary initialization of shared records */
+ for(i = 0; i < shared_rec_count; i++)
+ {
+ rec_ref = darshan_lookup_record_ref(stdio_runtime->rec_id_hash,
+ &shared_recs[i], sizeof(darshan_record_id));
+ assert(rec_ref);
+
+ rec_ref->file_rec->base_rec.rank = -1;
+ }
+
+ /* sort the array of files descending by rank so that we get all of the
+ * shared files (marked by rank -1) in a contiguous portion at end
+ * of the array
+ */
+ darshan_record_sort(stdio_rec_buf, stdio_rec_count, sizeof(struct darshan_stdio_file));
+
+ /* make *send_buf point to the shared files at the end of sorted array */
+ red_send_buf = &(stdio_rec_buf[stdio_rec_count-shared_rec_count]);
+
+ /* allocate memory for the reduction output on rank 0 */
+ if(my_rank == 0)
+ {
+ red_recv_buf = malloc(shared_rec_count * sizeof(struct darshan_stdio_file));
+ if(!red_recv_buf)
+ {
+ return;
+ }
+ }
+
+ /* construct a datatype for a STDIO file record. This is serving no purpose
+ * except to make sure we can do a reduction on proper boundaries
+ */
+ DARSHAN_MPI_CALL(PMPI_Type_contiguous)(sizeof(struct darshan_stdio_file),
+ MPI_BYTE, &red_type);
+ DARSHAN_MPI_CALL(PMPI_Type_commit)(&red_type);
+
+ /* register a STDIO file record reduction operator */
+ DARSHAN_MPI_CALL(PMPI_Op_create)(stdio_record_reduction_op, 1, &red_op);
+
+ /* reduce shared STDIO file records */
+ DARSHAN_MPI_CALL(PMPI_Reduce)(red_send_buf, red_recv_buf,
+ shared_rec_count, red_type, red_op, 0, mod_comm);
+
+ /* clean up reduction state */
+ if(my_rank == 0)
+ {
+ int tmp_ndx = stdio_rec_count - shared_rec_count;
+ memcpy(&(stdio_rec_buf[tmp_ndx]), red_recv_buf,
+ shared_rec_count * sizeof(struct darshan_stdio_file));
+ free(red_recv_buf);
+ }
+ else
+ {
+ stdio_rec_count -= shared_rec_count;
+ }
+
+ DARSHAN_MPI_CALL(PMPI_Type_free)(&red_type);
+ DARSHAN_MPI_CALL(PMPI_Op_free)(&red_op);
+ }
+
+ /* update output buffer size to account for shared file reduction */
+ *stdio_buf_sz = stdio_rec_count * sizeof(struct darshan_stdio_file);
+
+ /* shutdown internal structures used for instrumenting */
+ stdio_cleanup_runtime();
+
+ /* disable further instrumentation */
+ instrumentation_disabled = 1;
+
+ STDIO_UNLOCK();
+
+ return;
+}
+
+static struct stdio_file_record_ref *stdio_track_new_file_record(
+ darshan_record_id rec_id, const char *path)
+{
+ struct darshan_stdio_file *file_rec = NULL;
+ struct stdio_file_record_ref *rec_ref = NULL;
+ int ret;
+
+ rec_ref = malloc(sizeof(*rec_ref));
+ if(!rec_ref)
+ return(NULL);
+ memset(rec_ref, 0, sizeof(*rec_ref));
+
+ /* add a reference to this file record based on record id */
+ ret = darshan_add_record_ref(&(stdio_runtime->rec_id_hash), &rec_id,
+ sizeof(darshan_record_id), rec_ref);
+ if(ret == 0)
+ {
+ free(rec_ref);
+ return(NULL);
+ }
+
+ /* register the actual file record with darshan-core so it is persisted
+ * in the log file
+ */
+ file_rec = darshan_core_register_record(
+ rec_id,
+ path,
+ DARSHAN_STDIO_MOD,
+ sizeof(struct darshan_stdio_file),
+ NULL);
+
+ if(!file_rec)
+ {
+ darshan_delete_record_ref(&(stdio_runtime->rec_id_hash),
+ &rec_id, sizeof(darshan_record_id));
+ free(rec_ref);
+ return(NULL);
+ }
+
+ /* registering this file record was successful, so initialize some fields */
+ file_rec->base_rec.id = rec_id;
+ file_rec->base_rec.rank = my_rank;
+ rec_ref->file_rec = file_rec;
+ stdio_runtime->file_rec_count++;
+
+ return(rec_ref);
+
+}
+
+static void stdio_cleanup_runtime()
+{
+ darshan_clear_record_refs(&(stdio_runtime->stream_hash), 0);
+ darshan_clear_record_refs(&(stdio_runtime->rec_id_hash), 1);
+
+ free(stdio_runtime);
+ stdio_runtime = NULL;
+
+ return;
+}
+
+/*
+ * Local variables:
+ * c-indent-level: 4
+ * c-basic-offset: 4
+ * End:
+ *
+ * vim: ts=8 sts=4 sw=4 expandtab
+ */
=====================================
darshan-runtime/share/ld-opts/darshan-base-ld-opts.in
=====================================
--- a/darshan-runtime/share/ld-opts/darshan-base-ld-opts.in
+++ b/darshan-runtime/share/ld-opts/darshan-base-ld-opts.in
@@ -3,3 +3,4 @@
@@darshan_share_path@/ld-opts/darshan-posix-ld-opts
@@darshan_share_path@/ld-opts/darshan-hdf5-ld-opts
@@darshan_share_path@/ld-opts/darshan-pnetcdf-ld-opts
+@@darshan_share_path@/ld-opts/darshan-stdio-ld-opts
=====================================
darshan-runtime/share/ld-opts/darshan-posix-ld-opts
=====================================
--- a/darshan-runtime/share/ld-opts/darshan-posix-ld-opts
+++ b/darshan-runtime/share/ld-opts/darshan-posix-ld-opts
@@ -2,8 +2,6 @@
--wrap=open64
--wrap=creat
--wrap=creat64
---wrap=fopen
---wrap=fopen64
--wrap=mkstemp
--wrap=mkostemp
--wrap=mkstemps
@@ -16,11 +14,8 @@
--wrap=pwrite64
--wrap=readv
--wrap=writev
---wrap=fread
---wrap=fwrite
--wrap=lseek
--wrap=lseek64
---wrap=fseek
--wrap=__xstat
--wrap=__xstat64
--wrap=__lxstat
@@ -32,7 +27,6 @@
--wrap=fsync
--wrap=fdatasync
--wrap=close
---wrap=fclose
--wrap=aio_read
--wrap=aio_write
--wrap=aio_read64
=====================================
darshan-runtime/share/ld-opts/darshan-stdio-ld-opts
=====================================
--- /dev/null
+++ b/darshan-runtime/share/ld-opts/darshan-stdio-ld-opts
@@ -0,0 +1,29 @@
+--undefined=__wrap_fopen
+--wrap=fopen
+--wrap=fopen64
+--wrap=fdopen
+--wrap=freopen
+--wrap=freopen64
+--wrap=fflush
+--wrap=fclose
+--wrap=fwrite
+--wrap=fread
+--wrap=fgetc
+--wrap=fscanf
+--wrap=vfscanf
+--wrap=_IO_getc
+--wrap=_IO_putc
+--wrap=getw
+--wrap=fgets
+--wrap=fseek
+--wrap=fseeko
+--wrap=fseeko64
+--wrap=fprintf
+--wrap=vfprintf
+--wrap=fputc
+--wrap=fputs
+--wrap=putw
+--wrap=fsetpos
+--wrap=fsetpos64
+--wrap=rewind
+--wrap=__isoc99_fscanf
=====================================
darshan-stdio-log-format.h
=====================================
--- /dev/null
+++ b/darshan-stdio-log-format.h
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2015 University of Chicago.
+ * See COPYRIGHT notice in top-level directory.
+ *
+ */
+
+#ifndef __DARSHAN_STDIO_LOG_FORMAT_H
+#define __DARSHAN_STDIO_LOG_FORMAT_H
+
+/* current log format version, to support backwards compatibility */
+#define DARSHAN_STDIO_VER 1
+
+#define STDIO_COUNTERS \
+ /* count of fopens */\
+ X(STDIO_OPENS) \
+ /* number of reads */ \
+ X(STDIO_READS) \
+ /* number of writes */ \
+ X(STDIO_WRITES) \
+ /* count of seeks */\
+ X(STDIO_SEEKS) \
+ /* count of flushes */\
+ X(STDIO_FLUSHES) \
+ /* total bytes written */ \
+ X(STDIO_BYTES_WRITTEN) \
+ /* total bytes read */ \
+ X(STDIO_BYTES_READ) \
+ /* maximum byte (offset) read */\
+ X(STDIO_MAX_BYTE_READ) \
+ /* maximum byte (offset) written */\
+ X(STDIO_MAX_BYTE_WRITTEN) \
+ /* end of counters */\
+ X(STDIO_NUM_INDICES)
+
+#define STDIO_F_COUNTERS \
+ /* cumulative meta time */\
+ X(STDIO_F_META_TIME) \
+ /* cumulative write time */\
+ X(STDIO_F_WRITE_TIME) \
+ /* cumulative read time */\
+ X(STDIO_F_READ_TIME) \
+ /* timestamp of first open */\
+ X(STDIO_F_OPEN_START_TIMESTAMP) \
+ /* timestamp of first close */\
+ X(STDIO_F_CLOSE_START_TIMESTAMP) \
+ /* timestamp of first write */\
+ X(STDIO_F_WRITE_START_TIMESTAMP) \
+ /* timestamp of first read */\
+ X(STDIO_F_READ_START_TIMESTAMP) \
+ /* timestamp of last open completion */\
+ X(STDIO_F_OPEN_END_TIMESTAMP) \
+ /* timestamp of last close completion */\
+ X(STDIO_F_CLOSE_END_TIMESTAMP) \
+ /* timestamp of last write completion */\
+ X(STDIO_F_WRITE_END_TIMESTAMP) \
+ /* timestamp of last read completion */\
+ X(STDIO_F_READ_END_TIMESTAMP) \
+ /* end of counters */\
+ X(STDIO_F_NUM_INDICES)
+
+#define X(a) a,
+/* integer counters for the "STDIO" module */
+enum darshan_stdio_indices
+{
+ STDIO_COUNTERS
+};
+
+/* floating point counters for the "STDIO" module */
+enum darshan_stdio_f_indices
+{
+ STDIO_F_COUNTERS
+};
+#undef X
+
+/* the darshan_stdio_record structure encompasses the high-level data/counters
+ * which would actually be logged to file by Darshan for the "STDIO"
+ * module. This logs the following data for each record:
+ * - a corresponding Darshan record identifier
+ * - the rank of the process responsible for the record
+ * - integer I/O counters (operation counts, I/O sizes, etc.)
+ * - floating point I/O counters (timestamps, cumulative timers, etc.)
+ */
+struct darshan_stdio_file
+{
+ struct darshan_base_record base_rec;
+ int64_t counters[STDIO_NUM_INDICES];
+ double fcounters[STDIO_F_NUM_INDICES];
+};
+
+#endif /* __DARSHAN_STDIO_LOG_FORMAT_H */
=====================================
darshan-test/regression/test-cases/fprintf-fscanf-test.sh
=====================================
--- /dev/null
+++ b/darshan-test/regression/test-cases/fprintf-fscanf-test.sh
@@ -0,0 +1,53 @@
+#!/bin/bash
+
+PROG=fprintf-fscanf-test
+
+# set log file path; remove previous log if present
+export DARSHAN_LOGFILE=$DARSHAN_TMP/${PROG}.darshan
+rm -f ${DARSHAN_LOGFILE}
+
+# compile
+$DARSHAN_CC $DARSHAN_TESTDIR/test-cases/src/${PROG}.c -o $DARSHAN_TMP/${PROG}
+if [ $? -ne 0 ]; then
+ echo "Error: failed to compile ${PROG}" 1>&2
+ exit 1
+fi
+
+# execute
+$DARSHAN_RUNJOB $DARSHAN_TMP/${PROG} -f $DARSHAN_TMP/${PROG}.tmp.dat
+if [ $? -ne 0 ]; then
+ echo "Error: failed to execute ${PROG}" 1>&2
+ exit 1
+fi
+
+# parse log
+$DARSHAN_PATH/bin/darshan-parser $DARSHAN_LOGFILE > $DARSHAN_TMP/${PROG}.darshan.txt
+if [ $? -ne 0 ]; then
+ echo "Error: failed to parse ${DARSHAN_LOGFILE}" 1>&2
+ exit 1
+fi
+
+# check results
+
+STDIO_OPENS=`grep STDIO_OPENS $DARSHAN_TMP/${PROG}.darshan.txt | cut -f 5`
+if [ ! "$STDIO_OPENS" -eq 4 ]; then
+ echo "Error: STDIO open count of $STDIO_OPENS is incorrect" 1>&2
+ exit 1
+fi
+
+# this will check fprintf counting
+STDIO_BYTES_WRITTEN=`grep STDIO_BYTES_WRITTEN $DARSHAN_TMP/${PROG}.darshan.txt | cut -f 5`
+if [ ! "$STDIO_BYTES_WRITTEN" -eq 15 ]; then
+ echo "Error: STDIO bytes written count of $STDIO_BYTES_WRITTEN is incorrect" 1>&2
+ exit 1
+fi
+
+# this will check fscanf counting
+STDIO_BYTES_READ=`grep STDIO_BYTES_READ $DARSHAN_TMP/${PROG}.darshan.txt | cut -f 5`
+if [ ! "$STDIO_BYTES_READ" -eq 15 ]; then
+ echo "Error: STDIO bytes read count of $STDIO_BYTES_READ is incorrect" 1>&2
+ exit 1
+fi
+
+
+exit 0
=====================================
darshan-test/regression/test-cases/src/fprintf-fscanf-test.c
=====================================
--- /dev/null
+++ b/darshan-test/regression/test-cases/src/fprintf-fscanf-test.c
@@ -0,0 +1,106 @@
+/*
+ * (C) 1995-2001 Clemson University and Argonne National Laboratory.
+ *
+ * See COPYING in top-level directory.
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/time.h>
+#include <mpi.h>
+#include <errno.h>
+#include <getopt.h>
+
+/* DEFAULT VALUES FOR OPTIONS */
+static char opt_file[256] = "test-fprintf-fscanf.out";
+
+/* function prototypes */
+static int parse_args(int argc, char **argv);
+static void usage(void);
+
+/* global vars */
+static int mynod = 0;
+static int nprocs = 1;
+
+int main(int argc, char **argv)
+{
+ int namelen;
+ char processor_name[MPI_MAX_PROCESSOR_NAME];
+ FILE *file;
+ char buffer[128] = {0};
+ int number = 0;
+
+ /* startup MPI and determine the rank of this process */
+ MPI_Init(&argc,&argv);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+ MPI_Comm_rank(MPI_COMM_WORLD, &mynod);
+ MPI_Get_processor_name(processor_name, &namelen);
+
+ /* parse the command line arguments */
+ parse_args(argc, argv);
+
+ if (mynod == 0) printf("# Using stdio calls.\n");
+
+ file = fopen(opt_file, "w+");
+ if(!file)
+ {
+ perror("fopen");
+ return(-1);
+ }
+
+ if(mynod == 0)
+ {
+ fprintf(file, "a number: %d", 12345);
+ fseek(file, 0, SEEK_SET);
+ fscanf(file, "a number: %d", &number);
+ }
+
+ fclose(file);
+
+ MPI_Finalize();
+ return(0);
+}
+
+static int parse_args(int argc, char **argv)
+{
+ int c;
+
+ while ((c = getopt(argc, argv, "f:")) != EOF) {
+ switch (c) {
+ case 'f': /* filename */
+ strncpy(opt_file, optarg, 255);
+ break;
+ case '?': /* unknown */
+ if (mynod == 0)
+ usage();
+ exit(1);
+ default:
+ break;
+ }
+ }
+ return(0);
+}
+
+static void usage(void)
+{
+ printf("Usage: stdio-test [<OPTIONS>...]\n");
+ printf("\n<OPTIONS> is one of\n");
+ printf(" -f filename [default: /foo/test.out]\n");
+ printf(" -h print this help\n");
+}
+
+/*
+ * Local variables:
+ * c-indent-level: 3
+ * c-basic-offset: 3
+ * tab-width: 3
+ *
+ * vim: ts=3
+ * End:
+ */
+
+
=====================================
darshan-test/regression/test-cases/src/stdio-test.c
=====================================
--- /dev/null
+++ b/darshan-test/regression/test-cases/src/stdio-test.c
@@ -0,0 +1,105 @@
+/*
+ * (C) 1995-2001 Clemson University and Argonne National Laboratory.
+ *
+ * See COPYING in top-level directory.
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/time.h>
+#include <mpi.h>
+#include <errno.h>
+#include <getopt.h>
+
+/* DEFAULT VALUES FOR OPTIONS */
+static char opt_file[256] = "test.out";
+
+/* function prototypes */
+static int parse_args(int argc, char **argv);
+static void usage(void);
+
+/* global vars */
+static int mynod = 0;
+static int nprocs = 1;
+
+int main(int argc, char **argv)
+{
+ int namelen;
+ char processor_name[MPI_MAX_PROCESSOR_NAME];
+ FILE *file;
+ char buffer[128] = {0};
+
+ /* startup MPI and determine the rank of this process */
+ MPI_Init(&argc,&argv);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+ MPI_Comm_rank(MPI_COMM_WORLD, &mynod);
+ MPI_Get_processor_name(processor_name, &namelen);
+
+ /* parse the command line arguments */
+ parse_args(argc, argv);
+
+ if (mynod == 0) printf("# Using stdio calls.\n");
+
+ file = fopen(opt_file, "w+");
+ if(!file)
+ {
+ perror("fopen");
+ return(-1);
+ }
+
+ if(mynod == 0)
+ {
+ fwrite("hello", 1, 6, file);
+ fseek(file, 0, SEEK_SET);
+ fread(buffer, 1, 1024, file);
+ }
+
+ fclose(file);
+
+ MPI_Finalize();
+ return(0);
+}
+
+static int parse_args(int argc, char **argv)
+{
+ int c;
+
+ while ((c = getopt(argc, argv, "f:")) != EOF) {
+ switch (c) {
+ case 'f': /* filename */
+ strncpy(opt_file, optarg, 255);
+ break;
+ case '?': /* unknown */
+ if (mynod == 0)
+ usage();
+ exit(1);
+ default:
+ break;
+ }
+ }
+ return(0);
+}
+
+static void usage(void)
+{
+ printf("Usage: stdio-test [<OPTIONS>...]\n");
+ printf("\n<OPTIONS> is one of\n");
+ printf(" -f filename [default: /foo/test.out]\n");
+ printf(" -h print this help\n");
+}
+
+/*
+ * Local variables:
+ * c-indent-level: 3
+ * c-basic-offset: 3
+ * tab-width: 3
+ *
+ * vim: ts=3
+ * End:
+ */
+
+
=====================================
darshan-test/regression/test-cases/stdio-test.sh
=====================================
--- /dev/null
+++ b/darshan-test/regression/test-cases/stdio-test.sh
@@ -0,0 +1,90 @@
+#!/bin/bash
+
+PROG=stdio-test
+
+# set log file path; remove previous log if present
+export DARSHAN_LOGFILE=$DARSHAN_TMP/${PROG}.darshan
+rm -f ${DARSHAN_LOGFILE}
+
+# compile
+$DARSHAN_CC $DARSHAN_TESTDIR/test-cases/src/${PROG}.c -o $DARSHAN_TMP/${PROG}
+if [ $? -ne 0 ]; then
+ echo "Error: failed to compile ${PROG}" 1>&2
+ exit 1
+fi
+
+# execute
+$DARSHAN_RUNJOB $DARSHAN_TMP/${PROG} -f $DARSHAN_TMP/${PROG}.tmp.dat
+if [ $? -ne 0 ]; then
+ echo "Error: failed to execute ${PROG}" 1>&2
+ exit 1
+fi
+
+# parse log
+$DARSHAN_PATH/bin/darshan-parser $DARSHAN_LOGFILE > $DARSHAN_TMP/${PROG}.darshan.txt
+if [ $? -ne 0 ]; then
+ echo "Error: failed to parse ${DARSHAN_LOGFILE}" 1>&2
+ exit 1
+fi
+
+# check results
+
+# check at least one counter from each general open/read/write/seek category
+
+STDIO_OPENS=`grep STDIO_OPENS $DARSHAN_TMP/${PROG}.darshan.txt | cut -f 5`
+if [ ! "$STDIO_OPENS" -gt 0 ]; then
+ echo "Error: STDIO open count of $STDIO_OPENS is incorrect" 1>&2
+ exit 1
+fi
+STDIO_SEEKS=`grep STDIO_SEEKS $DARSHAN_TMP/${PROG}.darshan.txt | cut -f 5`
+if [ ! "$STDIO_SEEKS" -gt 0 ]; then
+ echo "Error: STDIO open count of $STDIO_SEEKS is incorrect" 1>&2
+ exit 1
+fi
+STDIO_BYTES_WRITTEN=`grep STDIO_BYTES_WRITTEN $DARSHAN_TMP/${PROG}.darshan.txt | cut -f 5`
+if [ ! "$STDIO_BYTES_WRITTEN" -eq 6 ]; then
+ echo "Error: STDIO open count of $STDIO_BYTES_WRITTEN is incorrect" 1>&2
+ exit 1
+fi
+STDIO_BYTES_READ=`grep STDIO_BYTES_READ $DARSHAN_TMP/${PROG}.darshan.txt | cut -f 5`
+if [ ! "$STDIO_BYTES_READ" -eq 6 ]; then
+ echo "Error: STDIO open count of $STDIO_BYTES_READ is incorrect" 1>&2
+ exit 1
+fi
+
+
+# make sure that some of the floating point counters are valid
+# use bc for floating point comparison
+STDIO_F_OPEN_START_TIMESTAMP=`grep STDIO_F_OPEN_START_TIMESTAMP $DARSHAN_TMP/${PROG}.darshan.txt | cut -f 5`
+if [ ! $(echo "$STDIO_F_OPEN_START_TIMESTAMP > 0" | bc -l) ]; then
+ echo "Error: counter is incorrect" 1>&2
+ exit 1
+fi
+STDIO_F_OPEN_END_TIMESTAMP=`grep STDIO_F_OPEN_END_TIMESTAMP $DARSHAN_TMP/${PROG}.darshan.txt | cut -f 5`
+if [ ! $(echo "$STDIO_F_OPEN_END_TIMESTAMP > 0" | bc -l) ]; then
+ echo "Error: counter is incorrect" 1>&2
+ exit 1
+fi
+STDIO_F_META_TIME=`grep STDIO_F_META_TIME $DARSHAN_TMP/${PROG}.darshan.txt | cut -f 5`
+if [ ! $(echo "$STDIO_F_META_TIME > 0" | bc -l) ]; then
+ echo "Error: counter is incorrect" 1>&2
+ exit 1
+fi
+STDIO_F_WRITE_TIME=`grep STDIO_F_WRITE_TIME $DARSHAN_TMP/${PROG}.darshan.txt | cut -f 5`
+if [ ! $(echo "$STDIO_F_WRITE_TIME > 0" | bc -l) ]; then
+ echo "Error: counter is incorrect" 1>&2
+ exit 1
+fi
+STDIO_F_CLOSE_START_TIMESTAMP=`grep STDIO_F_CLOSE_START_TIMESTAMP $DARSHAN_TMP/${PROG}.darshan.txt | cut -f 5`
+if [ ! $(echo "$STDIO_F_CLOSE_START_TIMESTAMP > 0" | bc -l) ]; then
+ echo "Error: counter is incorrect" 1>&2
+ exit 1
+fi
+STDIO_F_CLOSE_END_TIMESTAMP=`grep STDIO_F_CLOSE_END_TIMESTAMP $DARSHAN_TMP/${PROG}.darshan.txt | cut -f 5`
+if [ ! $(echo "$STDIO_F_CLOSE_END_TIMESTAMP > 0" | bc -l) ]; then
+ echo "Error: counter is incorrect" 1>&2
+ exit 1
+fi
+
+
+exit 0
=====================================
darshan-util/Makefile.in
=====================================
--- a/darshan-util/Makefile.in
+++ b/darshan-util/Makefile.in
@@ -13,10 +13,10 @@ libdir = $(DESTDIR)@libdir@
pkgconfigdir = $(DESTDIR)$(libdir)/pkgconfig
DARSHAN_LOG_FORMAT = $(srcdir)/../darshan-log-format.h
-DARSHAN_MOD_LOG_FORMATS = $(srcdir)/../darshan-posix-log-format.h $(srcdir)/../darshan-mpiio-log-format.h $(srcdir)/../darshan-hdf5-log-format.h $(srcdir)/../darshan-pnetcdf-log-format.h $(srcdir)/../darshan-lustre-log-format.h
-DARSHAN_MOD_LOGUTIL_HEADERS = darshan-posix-logutils.h darshan-mpiio-logutils.h darshan-hdf5-logutils.h darshan-pnetcdf-logutils.h darshan-lustre-logutils.h
-DARSHAN_STATIC_MOD_OBJS = darshan-posix-logutils.o darshan-mpiio-logutils.o darshan-hdf5-logutils.o darshan-pnetcdf-logutils.o darshan-bgq-logutils.o darshan-lustre-logutils.o
-DARSHAN_DYNAMIC_MOD_OBJS = darshan-posix-logutils.po darshan-mpiio-logutils.po darshan-hdf5-logutils.po darshan-pnetcdf-logutils.po darshan-bgq-logutils.po darshan-lustre-logutils.po
+DARSHAN_MOD_LOG_FORMATS = $(srcdir)/../darshan-posix-log-format.h $(srcdir)/../darshan-mpiio-log-format.h $(srcdir)/../darshan-hdf5-log-format.h $(srcdir)/../darshan-pnetcdf-log-format.h $(srcdir)/../darshan-bgq-log-format.h $(srcdir)/../darshan-lustre-log-format.h $(srcdir)/../darshan-stdio-log-format.h
+DARSHAN_MOD_LOGUTIL_HEADERS = darshan-posix-logutils.h darshan-mpiio-logutils.h darshan-hdf5-logutils.h darshan-pnetcdf-logutils.h darshan-bgq-logutils.h darshan-lustre-logutils.h darshan-stdio-logutils.h
+DARSHAN_STATIC_MOD_OBJS = darshan-posix-logutils.o darshan-mpiio-logutils.o darshan-hdf5-logutils.o darshan-pnetcdf-logutils.o darshan-bgq-logutils.o darshan-lustre-logutils.o darshan-stdio-logutils.o
+DARSHAN_DYNAMIC_MOD_OBJS = darshan-posix-logutils.po darshan-mpiio-logutils.po darshan-hdf5-logutils.po darshan-pnetcdf-logutils.po darshan-bgq-logutils.po darshan-lustre-logutils.po darshan-stdio-logutils.po
DARSHAN_ENABLE_SHARED=@DARSHAN_ENABLE_SHARED@
@@ -86,6 +86,11 @@ darshan-lustre-logutils.o: darshan-lustre-logutils.c darshan-logutils.h darshan-
darshan-lustre-logutils.po: darshan-lustre-logutils.c darshan-logutils.h darshan-lustre-logutils.h $(DARSHAN_LOG_FORMAT) $(srcdir)/../darshan-lustre-log-format.h | uthash-1.9.2
$(CC) $(CFLAGS_SHARED) -c $< -o $@
+darshan-stdio-logutils.o: darshan-stdio-logutils.c darshan-logutils.h darshan-stdio-logutils.h $(DARSHAN_LOG_FORMAT) $(srcdir)/../darshan-stdio-log-format.h | uthash-1.9.2
+ $(CC) $(CFLAGS) -c $< -o $@
+darshan-stdio-logutils.po: darshan-stdio-logutils.c darshan-logutils.h darshan-stdio-logutils.h $(DARSHAN_LOG_FORMAT) $(srcdir)/../darshan-stdio-log-format.h | uthash-1.9.2
+ $(CC) $(CFLAGS_SHARED) -c $< -o $@
+
libdarshan-util.a: darshan-logutils.o $(DARSHAN_STATIC_MOD_OBJS)
ar rcs libdarshan-util.a $^
@@ -141,12 +146,14 @@ endif
install -m 644 $(srcdir)/darshan-pnetcdf-logutils.h $(includedir)
install -m 644 $(srcdir)/darshan-bgq-logutils.h $(includedir)
install -m 644 $(srcdir)/darshan-null-logutils.h $(includedir)
+ install -m 644 $(srcdir)/darshan-stdio-logutils.h $(includedir)
install -m 644 $(srcdir)/../darshan-null-log-format.h $(includedir)
install -m 644 $(srcdir)/../darshan-posix-log-format.h $(includedir)
install -m 644 $(srcdir)/../darshan-mpiio-log-format.h $(includedir)
install -m 644 $(srcdir)/../darshan-hdf5-log-format.h $(includedir)
install -m 644 $(srcdir)/../darshan-pnetcdf-log-format.h $(includedir)
install -m 644 $(srcdir)/../darshan-bgq-log-format.h $(includedir)
+ install -m 644 $(srcdir)/../darshan-stdio-log-format.h $(includedir)
install -d $(includedir)/uthash-1.9.2
install -d $(includedir)/uthash-1.9.2/src
install -m 644 uthash-1.9.2/src/uthash.h $(includedir)/uthash-1.9.2/src/
=====================================
darshan-util/configure
=====================================
The diff for this file was not included because it is too large.
=====================================
darshan-util/darshan-logutils.h
=====================================
--- a/darshan-util/darshan-logutils.h
+++ b/darshan-util/darshan-logutils.h
@@ -126,6 +126,7 @@ extern struct darshan_mod_logutil_funcs *mod_logutils[];
#include "darshan-pnetcdf-logutils.h"
#include "darshan-bgq-logutils.h"
#include "darshan-lustre-logutils.h"
+#include "darshan-stdio-logutils.h"
darshan_fd darshan_log_open(const char *name);
darshan_fd darshan_log_create(const char *name, enum darshan_comp_type comp_type,
=====================================
darshan-util/darshan-stdio-logutils.c
=====================================
--- /dev/null
+++ b/darshan-util/darshan-stdio-logutils.c
@@ -0,0 +1,231 @@
+/*
+ * Copyright (C) 2015 University of Chicago.
+ * See COPYRIGHT notice in top-level directory.
+ *
+ */
+
+#define _GNU_SOURCE
+#include "darshan-util-config.h"
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <inttypes.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+
+#include "darshan-logutils.h"
+
+/* integer counter name strings for the STDIO module */
+#define X(a) #a,
+char *stdio_counter_names[] = {
+ STDIO_COUNTERS
+};
+
+/* floating point counter name strings for the STDIO module */
+char *stdio_f_counter_names[] = {
+ STDIO_F_COUNTERS
+};
+#undef X
+
+/* prototypes for each of the STDIO module's logutil functions */
+static int darshan_log_get_stdio_record(darshan_fd fd, void* stdio_buf);
+static int darshan_log_put_stdio_record(darshan_fd fd, void* stdio_buf, int ver);
+static void darshan_log_print_stdio_record(void *file_rec,
+ char *file_name, char *mnt_pt, char *fs_type, int ver);
+static void darshan_log_print_stdio_description(void);
+static void darshan_log_print_stdio_record_diff(void *file_rec1, char *file_name1,
+ void *file_rec2, char *file_name2);
+
+/* structure storing each function needed for implementing the darshan
+ * logutil interface. these functions are used for reading, writing, and
+ * printing module data in a consistent manner.
+ */
+struct darshan_mod_logutil_funcs stdio_logutils =
+{
+ .log_get_record = &darshan_log_get_stdio_record,
+ .log_put_record = &darshan_log_put_stdio_record,
+ .log_print_record = &darshan_log_print_stdio_record,
+ .log_print_description = &darshan_log_print_stdio_description,
+ .log_print_diff = &darshan_log_print_stdio_record_diff
+};
+
+/* retrieve a STDIO record from log file descriptor 'fd', storing the
+ * buffer in 'stdio_buf'. Return 1 on successful record read, 0 on no
+ * more data, and -1 on error.
+ */
+static int darshan_log_get_stdio_record(darshan_fd fd, void* stdio_buf)
+{
+ struct darshan_stdio_file *file;
+ int i;
+ int ret;
+
+ /* read a STDIO module record from the darshan log file */
+ ret = darshan_log_get_mod(fd, DARSHAN_STDIO_MOD, stdio_buf,
+ sizeof(struct darshan_stdio_file));
+ if(ret < 0)
+ return(-1);
+ else if(ret < sizeof(struct darshan_stdio_file))
+ return(0);
+ else
+ {
+ /* if the read was successful, do any necessary byte-swapping */
+ file = (struct darshan_stdio_file *)stdio_buf;
+ if(fd->swap_flag)
+ {
+ /* swap bytes if necessary */
+ DARSHAN_BSWAP64(&file->base_rec.id);
+ DARSHAN_BSWAP64(&file->base_rec.rank);
+ for(i=0; i<STDIO_NUM_INDICES; i++)
+ DARSHAN_BSWAP64(&file->counters[i]);
+ for(i=0; i<STDIO_F_NUM_INDICES; i++)
+ DARSHAN_BSWAP64(&file->fcounters[i]);
+ }
+
+ return(1);
+ }
+}
+
+/* write the STDIO record stored in 'stdio_buf' to log file descriptor 'fd'.
+ * Return 0 on success, -1 on failure
+ */
+static int darshan_log_put_stdio_record(darshan_fd fd, void* stdio_buf, int ver)
+{
+ struct darshan_stdio_file *rec = (struct darshan_stdio_file *)stdio_buf;
+ int ret;
+
+ /* append STDIO record to darshan log file */
+ ret = darshan_log_put_mod(fd, DARSHAN_STDIO_MOD, rec,
+ sizeof(struct darshan_stdio_file), ver);
+ if(ret < 0)
+ return(-1);
+
+ return(0);
+}
+
+/* print all I/O data record statistics for the given STDIO record */
+static void darshan_log_print_stdio_record(void *file_rec, char *file_name,
+ char *mnt_pt, char *fs_type, int ver)
+{
+ int i;
+ struct darshan_stdio_file *stdio_rec =
+ (struct darshan_stdio_file *)file_rec;
+
+ /* print each of the integer and floating point counters for the STDIO module */
+ for(i=0; i<STDIO_NUM_INDICES; i++)
+ {
+ /* macro defined in darshan-logutils.h */
+ DARSHAN_COUNTER_PRINT(darshan_module_names[DARSHAN_STDIO_MOD],
+ stdio_rec->base_rec.rank, stdio_rec->base_rec.id, stdio_counter_names[i],
+ stdio_rec->counters[i], file_name, mnt_pt, fs_type);
+ }
+
+ for(i=0; i<STDIO_F_NUM_INDICES; i++)
+ {
+ /* macro defined in darshan-logutils.h */
+ DARSHAN_F_COUNTER_PRINT(darshan_module_names[DARSHAN_STDIO_MOD],
+ stdio_rec->base_rec.rank, stdio_rec->base_rec.id, stdio_f_counter_names[i],
+ stdio_rec->fcounters[i], file_name, mnt_pt, fs_type);
+ }
+
+ return;
+}
+
+/* print out a description of the STDIO module record fields */
+static void darshan_log_print_stdio_description()
+{
+ printf("\n# description of STDIO counters:\n");
+ printf("# STDIO_{OPENS|WRITES|READS|SEEKS|FLUSHES} are types of operations.\n");
+ printf("# STDIO_BYTES_*: total bytes read and written.\n");
+ printf("# STDIO_MAX_BYTE_*: highest offset byte read and written.\n");
+ printf("# STDIO_F_*_START_TIMESTAMP: timestamp of the first call to that type of function.\n");
+ printf("# STDIO_F_*_END_TIMESTAMP: timestamp of the completion of the last call to that type of function.\n");
+ printf("# STDIO_F_*_TIME: cumulative time spent in different types of functions.\n");
+
+ return;
+}
+
+static void darshan_log_print_stdio_record_diff(void *file_rec1, char *file_name1,
+ void *file_rec2, char *file_name2)
+{
+ struct darshan_stdio_file *file1 = (struct darshan_stdio_file *)file_rec1;
+ struct darshan_stdio_file *file2 = (struct darshan_stdio_file *)file_rec2;
+ int i;
+
+ /* NOTE: we assume that both input records are the same module format version */
+
+ for(i=0; i<STDIO_NUM_INDICES; i++)
+ {
+ if(!file2)
+ {
+ printf("- ");
+ DARSHAN_COUNTER_PRINT(darshan_module_names[DARSHAN_STDIO_MOD],
+ file1->base_rec.rank, file1->base_rec.id, stdio_counter_names[i],
+ file1->counters[i], file_name1, "", "");
+
+ }
+ else if(!file1)
+ {
+ printf("+ ");
+ DARSHAN_COUNTER_PRINT(darshan_module_names[DARSHAN_STDIO_MOD],
+ file2->base_rec.rank, file2->base_rec.id, stdio_counter_names[i],
+ file2->counters[i], file_name2, "", "");
+ }
+ else if(file1->counters[i] != file2->counters[i])
+ {
+ printf("- ");
+ DARSHAN_COUNTER_PRINT(darshan_module_names[DARSHAN_STDIO_MOD],
+ file1->base_rec.rank, file1->base_rec.id, stdio_counter_names[i],
+ file1->counters[i], file_name1, "", "");
+ printf("+ ");
+ DARSHAN_COUNTER_PRINT(darshan_module_names[DARSHAN_STDIO_MOD],
+ file2->base_rec.rank, file2->base_rec.id, stdio_counter_names[i],
+ file2->counters[i], file_name2, "", "");
+ }
+ }
+
+ for(i=0; i<STDIO_F_NUM_INDICES; i++)
+ {
+ if(!file2)
+ {
+ printf("- ");
+ DARSHAN_F_COUNTER_PRINT(darshan_module_names[DARSHAN_STDIO_MOD],
+ file1->base_rec.rank, file1->base_rec.id, stdio_f_counter_names[i],
+ file1->fcounters[i], file_name1, "", "");
+
+ }
+ else if(!file1)
+ {
+ printf("+ ");
+ DARSHAN_F_COUNTER_PRINT(darshan_module_names[DARSHAN_STDIO_MOD],
+ file2->base_rec.rank, file2->base_rec.id, stdio_f_counter_names[i],
+ file2->fcounters[i], file_name2, "", "");
+ }
+ else if(file1->fcounters[i] != file2->fcounters[i])
+ {
+ printf("- ");
+ DARSHAN_F_COUNTER_PRINT(darshan_module_names[DARSHAN_STDIO_MOD],
+ file1->base_rec.rank, file1->base_rec.id, stdio_f_counter_names[i],
+ file1->fcounters[i], file_name1, "", "");
+ printf("+ ");
+ DARSHAN_F_COUNTER_PRINT(darshan_module_names[DARSHAN_STDIO_MOD],
+ file2->base_rec.rank, file2->base_rec.id, stdio_f_counter_names[i],
+ file2->fcounters[i], file_name2, "", "");
+ }
+ }
+
+ return;
+}
+
+
+/*
+ * Local variables:
+ * c-indent-level: 4
+ * c-basic-offset: 4
+ * End:
+ *
+ * vim: ts=8 sts=4 sw=4 expandtab
+ */
=====================================
darshan-util/darshan-stdio-logutils.h
=====================================
--- /dev/null
+++ b/darshan-util/darshan-stdio-logutils.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright (C) 2015 University of Chicago.
+ * See COPYRIGHT notice in top-level directory.
+ *
+ */
+
+#ifndef __DARSHAN_STDIO_LOG_UTILS_H
+#define __DARSHAN_STDIO_LOG_UTILS_H
+
+/* declare STDIO module counter name strings and logutil definition as
+ * extern variables so they can be used in other utilities
+ */
+extern char *stdio_counter_names[];
+extern char *stdio_f_counter_names[];
+
+extern struct darshan_mod_logutil_funcs stdio_logutils;
+
+#endif
=====================================
darshan-util/darshan-util-config.h.in
=====================================
--- a/darshan-util/darshan-util-config.h.in
+++ b/darshan-util/darshan-util-config.h.in
@@ -54,6 +54,9 @@
/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME
+/* Define to the home page for this package. */
+#undef PACKAGE_URL
+
/* Define to the version of this package. */
#undef PACKAGE_VERSION
View it on GitLab: https://xgitlab.cels.anl.gov/darshan/darshan/compare/2770f997eeb71e87401465da6348bc87b5d3c440...5c5e44529f283a8a2be44808af744b333133e756
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.mcs.anl.gov/pipermail/darshan-commits/attachments/20160706/42eee583/attachment-0001.html>
More information about the Darshan-commits
mailing list