[Darshan-commits] [Git][darshan/darshan][dev-stdio] convert stdio module to use new apis
Philip Carns
xgitlab at cels.anl.gov
Thu Jun 23 16:35:37 CDT 2016
Philip Carns pushed to branch dev-stdio at darshan / darshan
Commits:
ad6ea64f by Phil Carns at 2016-06-23T17:33:59-04:00
convert stdio module to use new apis
- eliminated 110 SLOC
- untested
- - - - -
2 changed files:
- darshan-runtime/lib/darshan-stdio.c
- darshan-stdio-log-format.h
Changes:
=====================================
darshan-runtime/lib/darshan-stdio.c
=====================================
--- a/darshan-runtime/lib/darshan-stdio.c
+++ b/darshan-runtime/lib/darshan-stdio.c
@@ -90,9 +90,6 @@
#include <libgen.h>
#include <pthread.h>
-#include "uthash.h"
-#include "utlist.h"
-
#include "darshan.h"
#include "darshan-dynamic.h"
@@ -125,67 +122,14 @@ DARSHAN_FORWARD_DECL(fsetpos, int, (FILE *stream, const fpos_t *pos));
DARSHAN_FORWARD_DECL(fsetpos64, int, (FILE *stream, const fpos_t *pos));
DARSHAN_FORWARD_DECL(rewind, void, (FILE *stream));
-/* The stdio_file_runtime structure maintains necessary runtime metadata
- * for the STDIO file record (darshan_stdio_record structure, defined in
- * darshan-stdio-log-format.h) pointed to by 'file_record'. This metadata
- * assists with the instrumenting of specific statistics in the file record.
- * 'hlink' is a hash table link structure used to add/remove this record
- * from the hash table of STDIO file records for this process.
- *
- * RATIONALE: the STDIO module needs to track some stateful, volatile
- * information about each open file (like the current file offset, most recent
- * access time, etc.) to aid in instrumentation, but this information can't be
- * stored in the darshan_stdio_record struct because we don't want it to appear in
- * the final darshan log file. We therefore associate a stdio_file_runtime
- * struct with each darshan_stdio_record struct in order to track this information.
- *
- * NOTE: There is a one-to-one mapping of stdio_file_runtime structs to
- * darshan_stdio_record structs.
- *
- * NOTE: The stdio_file_runtime struct contains a pointer to a darshan_stdio_record
- * struct (see the *file_record member) rather than simply embedding an entire
- * darshan_stdio_record struct. This is done so that all of the darshan_stdio_record
- * structs can be kept contiguous in memory as a single array to simplify
- * reduction, compression, and storage.
- */
-struct stdio_file_runtime
+/* structure to track stdio stats at runtime */
+struct stdio_file_record_ref
{
- struct darshan_stdio_record* file_record;
+ struct darshan_stdio_file* file_rec;
int64_t offset;
double last_meta_end;
double last_read_end;
double last_write_end;
- UT_hash_handle hlink;
-};
-
-/* The stdio_file_runtime_ref structure is used to associate a STDIO
- * stream with an already existing STDIO file record. This is
- * necessary as many STDIO I/O functions take only an input stream,
- * but STDIO file records are indexed by their full file paths (i.e., darshan
- * record identifiers for STDIO files are created by hashing the file path).
- * In other words, this structure is necessary as it allows us to look up a
- * file record either by a pathname (stdio_file_runtime) or by STDIO stream
- * (stdio_file_runtime_ref), depending on which parameters are
- * available. This structure includes another hash table link, since separate
- * hashes are maintained for stdio_file_runtime structures and stdio_file_runtime_ref
- * structures.
- *
- * RATIONALE: In theory the FILE* information could be included in the
- * stdio_file_runtime struct rather than in a separate structure here. The
- * reason we don't do that is because the same file could be opened multiple
- * times by a given process with different stream pointers and thus
- * simulataneously referenced using different stream pointers. This practice is
- * not common, but we must support it.
- *
- * NOTE: there are potentially multiple stdio_file_runtime_ref structures
- * referring to a single stdio_file_runtime structure. Most of the time there is
- * only one, however.
- */
-struct stdio_file_runtime_ref
-{
- struct stdio_file_runtime* file;
- FILE* stream;
- UT_hash_handle hlink;
};
/* The stdio_runtime structure maintains necessary state for storing
@@ -194,12 +138,9 @@ struct stdio_file_runtime_ref
*/
struct stdio_runtime
{
- struct stdio_file_runtime* file_runtime_array;
- struct darshan_stdio_record* file_record_array;
- int file_array_size;
- int file_array_ndx;
- struct stdio_file_runtime* file_hash;
- struct stdio_file_runtime_ref* stream_hash;
+ void *rec_id_hash;
+ void *stream_hash;
+ int file_rec_count;
};
static struct stdio_runtime *stdio_runtime = NULL;
@@ -209,82 +150,101 @@ static int darshan_mem_alignment = 1;
static int my_rank = -1;
static void stdio_runtime_initialize(void);
-static struct stdio_file_runtime* stdio_file_by_name(const char *name);
-static struct stdio_file_runtime* stdio_file_by_name_setstream(const char* name, FILE *stream);
-static struct stdio_file_runtime* stdio_file_by_stream(FILE* stream);
-static void stdio_file_close_stream(FILE *stream);
-
-static void stdio_begin_shutdown(void);
-static void stdio_get_output_data(MPI_Comm mod_comm, darshan_record_id *shared_recs,
- int shared_rec_count, void **stdio_buf, int *stdio_buf_sz);
-static void stdio_shutdown(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 int stdio_record_compare(const void* a, const void* b);
+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 { \
- struct stdio_file_runtime* file; \
- char* exclude; \
- int tmp_index = 0; \
+ darshan_record_id rec_id; \
+ struct stdio_file_record_ref* rec_ref; \
+ char *newpath; \
if(__ret == NULL) break; \
- while((exclude = darshan_path_exclusions[tmp_index])) { \
- if(!(strncmp(exclude, __path, strlen(exclude)))) \
- break; \
- tmp_index++; \
+ newpath = darshan_clean_file_path(__path); \
+ if(!newpath) newpath = (char*)__path; \
+ if(darshan_core_excluded_path(newpath)) { \
+ if(newpath != (char*)__path) free(newpath); \
+ break; \
} \
- if(exclude) break; \
- file = stdio_file_by_name_setstream(__path, __ret); \
- if(!file) break; \
- file->offset = 0; \
- file->file_record->counters[STDIO_OPENS] += 1; \
- if(file->file_record->fcounters[STDIO_F_OPEN_START_TIMESTAMP] == 0 || \
- file->file_record->fcounters[STDIO_F_OPEN_START_TIMESTAMP] > __tm1) \
- file->file_record->fcounters[STDIO_F_OPEN_START_TIMESTAMP] = __tm1; \
- file->file_record->fcounters[STDIO_F_OPEN_END_TIMESTAMP] = __tm2; \
- DARSHAN_TIMER_INC_NO_OVERLAP(file->file_record->fcounters[STDIO_F_META_TIME], __tm1, __tm2, file->last_meta_end); \
+ rec_id = darshan_core_gen_record_id(newpath); \
+ rec_ref = darshan_lookup_record_ref(stdio_runtime->rec_id_hash, &rec_id, sizeof(darshan_record_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; \
- struct stdio_file_runtime* file; \
- file = stdio_file_by_stream(__fp); \
- if(!file) break; \
- this_offset = file->offset; \
- file->offset = this_offset + __bytes; \
- if(file->file_record->counters[STDIO_MAX_BYTE_READ] < (this_offset + __bytes - 1)) \
- file->file_record->counters[STDIO_MAX_BYTE_READ] = (this_offset + __bytes - 1); \
- file->file_record->counters[STDIO_BYTES_READ] += __bytes; \
- file->file_record->counters[STDIO_READS] += 1; \
- if(file->file_record->fcounters[STDIO_F_READ_START_TIMESTAMP] == 0 || \
- file->file_record->fcounters[STDIO_F_READ_START_TIMESTAMP] > __tm1) \
- file->file_record->fcounters[STDIO_F_READ_START_TIMESTAMP] = __tm1; \
- file->file_record->fcounters[STDIO_F_READ_END_TIMESTAMP] = __tm2; \
- DARSHAN_TIMER_INC_NO_OVERLAP(file->file_record->fcounters[STDIO_F_READ_TIME], __tm1, __tm2, file->last_write_end); \
+ rec_ref = darshan_lookup_record_ref(stdio_runtime->stream_hash, &(__fp), sizeof(int)); \
+ 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; \
- struct stdio_file_runtime* file; \
- file = stdio_file_by_stream(__fp); \
- if(!file) break; \
- this_offset = file->offset; \
- file->offset = this_offset + __bytes; \
- if(file->file_record->counters[STDIO_MAX_BYTE_WRITTEN] < (this_offset + __bytes - 1)) \
- file->file_record->counters[STDIO_MAX_BYTE_WRITTEN] = (this_offset + __bytes - 1); \
- file->file_record->counters[STDIO_BYTES_WRITTEN] += __bytes; \
+ rec_ref = darshan_lookup_record_ref(stdio_runtime->stream_hash, &(__fp), sizeof(int)); \
+ 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) \
- file->file_record->counters[STDIO_FLUSHES] += 1; \
+ rec_ref->file_rec->counters[STDIO_FLUSHES] += 1; \
else \
- file->file_record->counters[STDIO_WRITES] += 1; \
- if(file->file_record->fcounters[STDIO_F_WRITE_START_TIMESTAMP] == 0 || \
- file->file_record->fcounters[STDIO_F_WRITE_START_TIMESTAMP] > __tm1) \
- file->file_record->fcounters[STDIO_F_WRITE_START_TIMESTAMP] = __tm1; \
- file->file_record->fcounters[STDIO_F_WRITE_END_TIMESTAMP] = __tm2; \
- DARSHAN_TIMER_INC_NO_OVERLAP(file->file_record->fcounters[STDIO_F_WRITE_TIME], __tm1, __tm2, file->last_write_end); \
+ 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)
@@ -298,10 +258,9 @@ FILE* DARSHAN_DECL(fopen)(const char *path, const char *mode)
ret = __real_fopen(path, mode);
tm2 = darshan_core_wtime();
- STDIO_LOCK();
- stdio_runtime_initialize();
+ STDIO_PRE_RECORD();
STDIO_RECORD_OPEN(ret, path, tm1, tm2);
- STDIO_UNLOCK();
+ STDIO_POST_RECORD();
return(ret);
}
@@ -317,10 +276,9 @@ FILE* DARSHAN_DECL(fopen64)(const char *path, const char *mode)
ret = __real_fopen64(path, mode);
tm2 = darshan_core_wtime();
- STDIO_LOCK();
- stdio_runtime_initialize();
+ STDIO_PRE_RECORD();
STDIO_RECORD_OPEN(ret, path, tm1, tm2);
- STDIO_UNLOCK();
+ STDIO_POST_RECORD();
return(ret);
}
@@ -336,10 +294,9 @@ FILE* DARSHAN_DECL(fdopen)(int fd, const char *mode)
ret = __real_fdopen(fd, mode);
tm2 = darshan_core_wtime();
- STDIO_LOCK();
- stdio_runtime_initialize();
+ STDIO_PRE_RECORD();
STDIO_RECORD_OPEN(ret, "UNKNOWN-FDOPEN", tm1, tm2);
- STDIO_UNLOCK();
+ STDIO_POST_RECORD();
return(ret);
}
@@ -355,10 +312,9 @@ FILE* DARSHAN_DECL(freopen)(const char *path, const char *mode, FILE *stream)
ret = __real_freopen(path, mode, stream);
tm2 = darshan_core_wtime();
- STDIO_LOCK();
- stdio_runtime_initialize();
+ STDIO_PRE_RECORD();
STDIO_RECORD_OPEN(ret, path, tm1, tm2);
- STDIO_UNLOCK();
+ STDIO_POST_RECORD();
return(ret);
}
@@ -374,10 +330,9 @@ FILE* DARSHAN_DECL(freopen64)(const char *path, const char *mode, FILE *stream)
ret = __real_freopen64(path, mode, stream);
tm2 = darshan_core_wtime();
- STDIO_LOCK();
- stdio_runtime_initialize();
+ STDIO_PRE_RECORD();
STDIO_RECORD_OPEN(ret, path, tm1, tm2);
- STDIO_UNLOCK();
+ STDIO_POST_RECORD();
return(ret);
}
@@ -394,20 +349,19 @@ int DARSHAN_DECL(fflush)(FILE *fp)
ret = __real_fflush(fp);
tm2 = darshan_core_wtime();
- STDIO_LOCK();
- stdio_runtime_initialize();
+ STDIO_PRE_RECORD();
if(ret >= 0)
STDIO_RECORD_WRITE(fp, 0, tm1, tm2, 1);
- STDIO_UNLOCK();
+ STDIO_POST_RECORD();
return(ret);
}
int DARSHAN_DECL(fclose)(FILE *fp)
{
- struct stdio_file_runtime* file;
double tm1, tm2;
int ret;
+ struct stdio_file_record_ref *rec_ref;
MAP_OR_FAIL(fclose);
@@ -415,21 +369,20 @@ int DARSHAN_DECL(fclose)(FILE *fp)
ret = __real_fclose(fp);
tm2 = darshan_core_wtime();
- STDIO_LOCK();
- stdio_runtime_initialize();
- file = stdio_file_by_stream(fp);
- if(file)
+ STDIO_PRE_RECORD();
+ rec_ref = darshan_lookup_record_ref(stdio_runtime->stream_hash, &fp, sizeof(fp));
+ if(rec_ref)
{
- if(file->file_record->fcounters[STDIO_F_CLOSE_START_TIMESTAMP] == 0 ||
- file->file_record->fcounters[STDIO_F_CLOSE_START_TIMESTAMP] > tm1)
- file->file_record->fcounters[STDIO_F_CLOSE_START_TIMESTAMP] = tm1;
- file->file_record->fcounters[STDIO_F_CLOSE_END_TIMESTAMP] = tm2;
+ 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(
- file->file_record->fcounters[STDIO_F_META_TIME],
- tm1, tm2, file->last_meta_end);
- stdio_file_close_stream(fp);
+ 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_UNLOCK();
+ STDIO_POST_RECORD();
return(ret);
}
@@ -445,11 +398,10 @@ size_t DARSHAN_DECL(fwrite)(const void *ptr, size_t size, size_t nmemb, FILE *st
ret = __real_fwrite(ptr, size, nmemb, stream);
tm2 = darshan_core_wtime();
- STDIO_LOCK();
- stdio_runtime_initialize();
+ STDIO_PRE_RECORD();
if(ret > 0)
STDIO_RECORD_WRITE(stream, size*ret, tm1, tm2, 0);
- STDIO_UNLOCK();
+ STDIO_POST_RECORD();
return(ret);
}
@@ -466,11 +418,10 @@ int DARSHAN_DECL(fputc)(int c, FILE *stream)
ret = __real_fputc(c, stream);
tm2 = darshan_core_wtime();
- STDIO_LOCK();
- stdio_runtime_initialize();
+ STDIO_PRE_RECORD();
if(ret != EOF)
STDIO_RECORD_WRITE(stream, 1, tm1, tm2, 0);
- STDIO_UNLOCK();
+ STDIO_POST_RECORD();
return(ret);
}
@@ -486,11 +437,10 @@ int DARSHAN_DECL(putw)(int w, FILE *stream)
ret = __real_putw(w, stream);
tm2 = darshan_core_wtime();
- STDIO_LOCK();
- stdio_runtime_initialize();
+ STDIO_PRE_RECORD();
if(ret != EOF)
STDIO_RECORD_WRITE(stream, sizeof(int), tm1, tm2, 0);
- STDIO_UNLOCK();
+ STDIO_POST_RECORD();
return(ret);
}
@@ -508,11 +458,10 @@ int DARSHAN_DECL(fputs)(const char *s, FILE *stream)
ret = __real_fputs(s, stream);
tm2 = darshan_core_wtime();
- STDIO_LOCK();
- stdio_runtime_initialize();
+ STDIO_PRE_RECORD();
if(ret != EOF && ret > 0)
STDIO_RECORD_WRITE(stream, strlen(s), tm1, tm2, 0);
- STDIO_UNLOCK();
+ STDIO_POST_RECORD();
return(ret);
}
@@ -531,11 +480,10 @@ int DARSHAN_DECL(vfprintf)(FILE *stream, const char *format, va_list ap)
end_off = ftell(stream);
tm2 = darshan_core_wtime();
- STDIO_LOCK();
- stdio_runtime_initialize();
+ STDIO_PRE_RECORD();
if(ret > 0)
STDIO_RECORD_WRITE(stream, (end_off-start_off), tm1, tm2, 0);
- STDIO_UNLOCK();
+ STDIO_POST_RECORD();
return(ret);
}
@@ -561,11 +509,10 @@ int DARSHAN_DECL(fprintf)(FILE *stream, const char *format, ...)
end_off = ftell(stream);
tm2 = darshan_core_wtime();
- STDIO_LOCK();
- stdio_runtime_initialize();
+ STDIO_PRE_RECORD();
if(ret > 0)
STDIO_RECORD_WRITE(stream, (end_off-start_off), tm1, tm2, 0);
- STDIO_UNLOCK();
+ STDIO_POST_RECORD();
return(ret);
}
@@ -581,11 +528,10 @@ size_t DARSHAN_DECL(fread)(void *ptr, size_t size, size_t nmemb, FILE *stream)
ret = __real_fread(ptr, size, nmemb, stream);
tm2 = darshan_core_wtime();
- STDIO_LOCK();
- stdio_runtime_initialize();
+ STDIO_PRE_RECORD();
if(ret > 0)
STDIO_RECORD_READ(stream, size*ret, tm1, tm2);
- STDIO_UNLOCK();
+ STDIO_POST_RECORD();
return(ret);
}
@@ -601,11 +547,10 @@ size_t DARSHAN_DECL(fgetc)(FILE *stream)
ret = __real_fgetc(stream);
tm2 = darshan_core_wtime();
- STDIO_LOCK();
- stdio_runtime_initialize();
+ STDIO_PRE_RECORD();
if(ret != EOF)
STDIO_RECORD_READ(stream, 1, tm1, tm2);
- STDIO_UNLOCK();
+ STDIO_POST_RECORD();
return(ret);
}
@@ -622,11 +567,10 @@ size_t DARSHAN_DECL(_IO_getc)(FILE *stream)
ret = __real__IO_getc(stream);
tm2 = darshan_core_wtime();
- STDIO_LOCK();
- stdio_runtime_initialize();
+ STDIO_PRE_RECORD();
if(ret != EOF)
STDIO_RECORD_READ(stream, 1, tm1, tm2);
- STDIO_UNLOCK();
+ STDIO_POST_RECORD();
return(ret);
}
@@ -643,11 +587,10 @@ size_t DARSHAN_DECL(_IO_putc)(int c, FILE *stream)
ret = __real__IO_putc(c, stream);
tm2 = darshan_core_wtime();
- STDIO_LOCK();
- stdio_runtime_initialize();
+ STDIO_PRE_RECORD();
if(ret != EOF)
STDIO_RECORD_WRITE(stream, 1, tm1, tm2, 0);
- STDIO_UNLOCK();
+ STDIO_POST_RECORD();
return(ret);
}
@@ -662,11 +605,10 @@ size_t DARSHAN_DECL(getw)(FILE *stream)
ret = __real_getw(stream);
tm2 = darshan_core_wtime();
- STDIO_LOCK();
- stdio_runtime_initialize();
+ STDIO_PRE_RECORD();
if(ret != EOF || ferror(stream) == 0)
STDIO_RECORD_READ(stream, sizeof(int), tm1, tm2);
- STDIO_UNLOCK();
+ STDIO_POST_RECORD();
return(ret);
}
@@ -694,11 +636,10 @@ int DARSHAN_DECL(__isoc99_fscanf)(FILE *stream, const char *format, ...)
end_off = ftell(stream);
tm2 = darshan_core_wtime();
- STDIO_LOCK();
- stdio_runtime_initialize();
+ STDIO_PRE_RECORD();
if(ret != 0)
STDIO_RECORD_READ(stream, (end_off-start_off), tm1, tm2);
- STDIO_UNLOCK();
+ STDIO_POST_RECORD();
return(ret);
}
@@ -724,11 +665,10 @@ int DARSHAN_DECL(fscanf)(FILE *stream, const char *format, ...)
end_off = ftell(stream);
tm2 = darshan_core_wtime();
- STDIO_LOCK();
- stdio_runtime_initialize();
+ STDIO_PRE_RECORD();
if(ret != 0)
STDIO_RECORD_READ(stream, (end_off-start_off), tm1, tm2);
- STDIO_UNLOCK();
+ STDIO_POST_RECORD();
return(ret);
}
@@ -747,11 +687,10 @@ int DARSHAN_DECL(vfscanf)(FILE *stream, const char *format, va_list ap)
end_off = ftell(stream);
tm2 = darshan_core_wtime();
- STDIO_LOCK();
- stdio_runtime_initialize();
+ STDIO_PRE_RECORD();
if(ret != 0)
STDIO_RECORD_READ(stream, end_off-start_off, tm1, tm2);
- STDIO_UNLOCK();
+ STDIO_POST_RECORD();
return(ret);
}
@@ -768,11 +707,10 @@ char* DARSHAN_DECL(fgets)(char *s, int size, FILE *stream)
ret = __real_fgets(s, size, stream);
tm2 = darshan_core_wtime();
- STDIO_LOCK();
- stdio_runtime_initialize();
+ STDIO_PRE_RECORD();
if(ret != NULL)
STDIO_RECORD_READ(stream, strlen(ret), tm1, tm2);
- STDIO_UNLOCK();
+ STDIO_POST_RECORD();
return(ret);
}
@@ -780,8 +718,8 @@ char* DARSHAN_DECL(fgets)(char *s, int size, FILE *stream)
void DARSHAN_DECL(rewind)(FILE *stream)
{
- struct stdio_file_runtime* file;
double tm1, tm2;
+ struct stdio_file_record_ref *rec_ref;
MAP_OR_FAIL(rewind);
@@ -789,18 +727,27 @@ void DARSHAN_DECL(rewind)(FILE *stream)
__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();
- stdio_runtime_initialize();
- file = stdio_file_by_stream(stream);
- if(file)
+ 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)
{
- file->offset = 0;
+ rec_ref->offset = 0;
DARSHAN_TIMER_INC_NO_OVERLAP(
- file->file_record->fcounters[STDIO_F_META_TIME],
- tm1, tm2, file->last_meta_end);
- file->file_record->counters[STDIO_SEEKS] += 1;
+ 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_UNLOCK();
+ STDIO_POST_RECORD();
return;
}
@@ -808,7 +755,7 @@ void DARSHAN_DECL(rewind)(FILE *stream)
int DARSHAN_DECL(fseek)(FILE *stream, long offset, int whence)
{
int ret;
- struct stdio_file_runtime* file;
+ struct stdio_file_record_ref *rec_ref;
double tm1, tm2;
MAP_OR_FAIL(fseek);
@@ -819,18 +766,17 @@ int DARSHAN_DECL(fseek)(FILE *stream, long offset, int whence)
if(ret >= 0)
{
- STDIO_LOCK();
- stdio_runtime_initialize();
- file = stdio_file_by_stream(stream);
- if(file)
+ STDIO_PRE_RECORD();
+ rec_ref = darshan_lookup_record_ref(stdio_runtime->stream_hash, &stream, sizeof(stream));
+ if(rec_ref)
{
- file->offset = ftell(stream);
+ rec_ref->offset = ftell(stream);
DARSHAN_TIMER_INC_NO_OVERLAP(
- file->file_record->fcounters[STDIO_F_META_TIME],
- tm1, tm2, file->last_meta_end);
- file->file_record->counters[STDIO_SEEKS] += 1;
+ 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_UNLOCK();
+ STDIO_POST_RECORD();
}
return(ret);
@@ -839,7 +785,7 @@ int DARSHAN_DECL(fseek)(FILE *stream, long offset, int whence)
int DARSHAN_DECL(fseeko)(FILE *stream, off_t offset, int whence)
{
int ret;
- struct stdio_file_runtime* file;
+ struct stdio_file_record_ref *rec_ref;
double tm1, tm2;
MAP_OR_FAIL(fseeko);
@@ -850,18 +796,17 @@ int DARSHAN_DECL(fseeko)(FILE *stream, off_t offset, int whence)
if(ret >= 0)
{
- STDIO_LOCK();
- stdio_runtime_initialize();
- file = stdio_file_by_stream(stream);
- if(file)
+ STDIO_PRE_RECORD();
+ rec_ref = darshan_lookup_record_ref(stdio_runtime->stream_hash, &stream, sizeof(stream));
+ if(rec_ref)
{
- file->offset = ftell(stream);
+ rec_ref->offset = ftell(stream);
DARSHAN_TIMER_INC_NO_OVERLAP(
- file->file_record->fcounters[STDIO_F_META_TIME],
- tm1, tm2, file->last_meta_end);
- file->file_record->counters[STDIO_SEEKS] += 1;
+ 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_UNLOCK();
+ STDIO_POST_RECORD();
}
return(ret);
@@ -870,7 +815,7 @@ int DARSHAN_DECL(fseeko)(FILE *stream, off_t offset, int whence)
int DARSHAN_DECL(fseeko64)(FILE *stream, off_t offset, int whence)
{
int ret;
- struct stdio_file_runtime* file;
+ struct stdio_file_record_ref *rec_ref;
double tm1, tm2;
MAP_OR_FAIL(fseeko64);
@@ -881,18 +826,17 @@ int DARSHAN_DECL(fseeko64)(FILE *stream, off_t offset, int whence)
if(ret >= 0)
{
- STDIO_LOCK();
- stdio_runtime_initialize();
- file = stdio_file_by_stream(stream);
- if(file)
+ STDIO_PRE_RECORD();
+ rec_ref = darshan_lookup_record_ref(stdio_runtime->stream_hash, &stream, sizeof(stream));
+ if(rec_ref)
{
- file->offset = ftell(stream);
+ rec_ref->offset = ftell(stream);
DARSHAN_TIMER_INC_NO_OVERLAP(
- file->file_record->fcounters[STDIO_F_META_TIME],
- tm1, tm2, file->last_meta_end);
- file->file_record->counters[STDIO_SEEKS] += 1;
+ 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_UNLOCK();
+ STDIO_POST_RECORD();
}
return(ret);
@@ -901,7 +845,7 @@ int DARSHAN_DECL(fseeko64)(FILE *stream, off_t offset, int whence)
int DARSHAN_DECL(fsetpos)(FILE *stream, const fpos_t *pos)
{
int ret;
- struct stdio_file_runtime* file;
+ struct stdio_file_record_ref *rec_ref;
double tm1, tm2;
MAP_OR_FAIL(fsetpos);
@@ -912,18 +856,17 @@ int DARSHAN_DECL(fsetpos)(FILE *stream, const fpos_t *pos)
if(ret >= 0)
{
- STDIO_LOCK();
- stdio_runtime_initialize();
- file = stdio_file_by_stream(stream);
- if(file)
+ STDIO_PRE_RECORD();
+ rec_ref = darshan_lookup_record_ref(stdio_runtime->stream_hash, &stream, sizeof(stream));
+ if(rec_ref)
{
- file->offset = ftell(stream);
+ rec_ref->offset = ftell(stream);
DARSHAN_TIMER_INC_NO_OVERLAP(
- file->file_record->fcounters[STDIO_F_META_TIME],
- tm1, tm2, file->last_meta_end);
- file->file_record->counters[STDIO_SEEKS] += 1;
+ 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_UNLOCK();
+ STDIO_POST_RECORD();
}
return(ret);
@@ -932,7 +875,7 @@ int DARSHAN_DECL(fsetpos)(FILE *stream, const fpos_t *pos)
int DARSHAN_DECL(fsetpos64)(FILE *stream, const fpos_t *pos)
{
int ret;
- struct stdio_file_runtime* file;
+ struct stdio_file_record_ref *rec_ref;
double tm1, tm2;
MAP_OR_FAIL(fsetpos64);
@@ -943,18 +886,17 @@ int DARSHAN_DECL(fsetpos64)(FILE *stream, const fpos_t *pos)
if(ret >= 0)
{
- STDIO_LOCK();
- stdio_runtime_initialize();
- file = stdio_file_by_stream(stream);
- if(file)
+ STDIO_PRE_RECORD();
+ rec_ref = darshan_lookup_record_ref(stdio_runtime->stream_hash, &stream, sizeof(stream));
+ if(rec_ref)
{
- file->offset = ftell(stream);
+ rec_ref->offset = ftell(stream);
DARSHAN_TIMER_INC_NO_OVERLAP(
- file->file_record->fcounters[STDIO_F_META_TIME],
- tm1, tm2, file->last_meta_end);
- file->file_record->counters[STDIO_SEEKS] += 1;
+ 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_UNLOCK();
+ STDIO_POST_RECORD();
}
return(ret);
@@ -968,13 +910,10 @@ int DARSHAN_DECL(fsetpos64)(FILE *stream, const fpos_t *pos)
/* initialize internal STDIO module data structures and register with darshan-core */
static void stdio_runtime_initialize()
{
- int mem_limit;
- struct darshan_module_funcs stdio_mod_fns =
- {
- .begin_shutdown = &stdio_begin_shutdown,
- .get_output_data = &stdio_get_output_data,
- .shutdown = &stdio_shutdown
- };
+ 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)
@@ -983,216 +922,115 @@ static void stdio_runtime_initialize()
/* register the stdio module with darshan core */
darshan_core_register_module(
DARSHAN_STDIO_MOD,
- &stdio_mod_fns,
+ &stdio_shutdown,
&my_rank,
- &mem_limit,
+ &stdio_buf_size,
&darshan_mem_alignment);
- /* return if no memory assigned by darshan core */
- if(mem_limit == 0)
+ /* 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)
- return;
- memset(stdio_runtime, 0, sizeof(*stdio_runtime));
-
- /* set maximum number of file records according to max memory limit */
- /* NOTE: maximum number of records is based on the size of a stdio file record */
- /* TODO: should we base memory usage off file record or total runtime structure sizes? */
- stdio_runtime->file_array_size = mem_limit / sizeof(struct darshan_stdio_record);
- stdio_runtime->file_array_ndx = 0;
-
- /* allocate array of runtime file records */
- stdio_runtime->file_runtime_array = malloc(stdio_runtime->file_array_size *
- sizeof(struct stdio_file_runtime));
- stdio_runtime->file_record_array = malloc(stdio_runtime->file_array_size *
- sizeof(struct darshan_stdio_record));
- if(!stdio_runtime->file_runtime_array || !stdio_runtime->file_record_array)
{
- stdio_runtime->file_array_size = 0;
+ darshan_core_unregister_module(DARSHAN_STDIO_MOD);
return;
}
- memset(stdio_runtime->file_runtime_array, 0, stdio_runtime->file_array_size *
- sizeof(struct stdio_file_runtime));
- memset(stdio_runtime->file_record_array, 0, stdio_runtime->file_array_size *
- sizeof(struct darshan_stdio_record));
-
- return;
+ memset(stdio_runtime, 0, sizeof(*stdio_runtime));
}
-/* get a STDIO file record for the given file path */
-static struct stdio_file_runtime* stdio_file_by_name(const char *name)
-{
- struct stdio_file_runtime *file = NULL;
- char *newname = NULL;
- darshan_record_id file_id;
- int file_alignment;
- int limit_flag;
-
- if(!stdio_runtime || instrumentation_disabled)
- return(NULL);
-
- newname = darshan_clean_file_path(name);
- if(!newname)
- newname = (char*)name;
-
- limit_flag = (stdio_runtime->file_array_ndx >= stdio_runtime->file_array_size);
-
- /* get a unique id for this file from darshan core */
- darshan_core_register_record(
- (void*)newname,
- strlen(newname),
- DARSHAN_STDIO_MOD,
- 1,
- limit_flag,
- &file_id,
- &file_alignment);
-
- /* the file record id is set to 0 if no memory is available for tracking
- * new records -- just fall through and ignore this record
- */
- if(file_id == 0)
- {
- if(newname != name)
- free(newname);
- return(NULL);
- }
-
- /* search the hash table for this file record, and return if found */
- HASH_FIND(hlink, stdio_runtime->file_hash, &file_id, sizeof(darshan_record_id), file);
- if(file)
- {
- if(newname != name)
- free(newname);
- return(file);
- }
-
- /* no existing record, assign a new file record from the global array */
- file = &(stdio_runtime->file_runtime_array[stdio_runtime->file_array_ndx]);
- file->file_record = &(stdio_runtime->file_record_array[stdio_runtime->file_array_ndx]);
- file->file_record->f_id = file_id;
- file->file_record->rank = my_rank;
-
- /* add new record to file hash table */
- HASH_ADD(hlink, stdio_runtime->file_hash, file_record->f_id, sizeof(darshan_record_id), file);
- stdio_runtime->file_array_ndx++;
-
- if(newname != name)
- free(newname);
- return(file);
-}
+/************************************************************************
+ * Functions exported by this module for coordinating with darshan-core *
+ ************************************************************************/
-/* get a STDIO file record for the given file path, and also create a
- * reference structure using the returned stream
- */
-static struct stdio_file_runtime* stdio_file_by_name_setstream(const char* name, FILE *stream)
+static void stdio_record_reduction_op(void* infile_v, void* inoutfile_v,
+ int *len, MPI_Datatype *datatype)
{
- struct stdio_file_runtime* file;
- struct stdio_file_runtime_ref* ref;
-
- if(!stdio_runtime || instrumentation_disabled)
- return(NULL);
-
- /* find file record by name first */
- file = stdio_file_by_name(name);
+ struct darshan_stdio_file tmp_file;
+ struct darshan_stdio_file *infile = infile_v;
+ struct darshan_stdio_file *inoutfile = inoutfile_v;
+ int i, j;
- if(!file)
- return(NULL);
+ assert(stdio_runtime);
- /* search hash table for existing file ref for this stream */
- HASH_FIND(hlink, stdio_runtime->stream_hash, &stream, sizeof(FILE*), ref);
- if(ref)
+ for(i=0; i<*len; i++)
{
- /* we have a reference. Make sure it points to the correct file
- * and return it
- */
- ref->file = file;
- return(file);
- }
-
- /* if we hit this point, then we don't have a reference for this stream
- * in the table yet. Add it.
- */
- ref = malloc(sizeof(*ref));
- if(!ref)
- return(NULL);
- memset(ref, 0, sizeof(*ref));
+ memset(&tmp_file, 0, sizeof(struct darshan_stdio_file));
+ tmp_file.base_rec.id = infile->base_rec.id;
+ tmp_file.base_rec.rank = -1;
- ref->file = file;
- ref->stream = stream;
- HASH_ADD(hlink, stdio_runtime->stream_hash, stream, sizeof(FILE*), ref);
-
- return(file);
-}
-
-/* get a STDIO file record for the given stream */
-static struct stdio_file_runtime* stdio_file_by_stream(FILE *stream)
-{
- struct stdio_file_runtime_ref* ref;
-
- if(!stdio_runtime || instrumentation_disabled)
- return(NULL);
-
- /* search hash table for existing file ref for this stream */
- HASH_FIND(hlink, stdio_runtime->stream_hash, &stream, sizeof(FILE*), ref);
- if(ref)
- return(ref->file);
+ /* 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];
+ }
- return(NULL);
-}
+ /* sum */
+ for(j=STDIO_F_META_TIME; j<=STDIO_F_READ_TIME; j++)
+ {
+ tmp_file.fcounters[j] = infile->fcounters[j] + inoutfile->fcounters[j];
+ }
-/* free up reference data structures for the given stream */
-static void stdio_file_close_stream(FILE *stream)
-{
- struct stdio_file_runtime_ref* ref;
+ /* 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];
+ }
- if(!stdio_runtime || instrumentation_disabled)
- return;
+ /* 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];
+ }
- /* search hash table for this stream */
- HASH_FIND(hlink, stdio_runtime->stream_hash, &stream, sizeof(FILE*), ref);
- if(ref)
- {
- /* we have a reference, delete it */
- HASH_DELETE(hlink, stdio_runtime->stream_hash, ref);
- free(ref);
+ /* update pointers */
+ *inoutfile = tmp_file;
+ inoutfile++;
+ infile++;
}
return;
}
-/************************************************************************
- * Functions exported by this module for coordinating with darshan-core *
- ************************************************************************/
-
-static void stdio_begin_shutdown()
-{
- assert(stdio_runtime);
-
- STDIO_LOCK();
- /* disable further instrumentation while Darshan shuts down */
- instrumentation_disabled = 1;
- STDIO_UNLOCK();
-
- return;
-}
-
-static void stdio_get_output_data(
+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_runtime *file;
+ 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_record *red_send_buf = NULL;
- struct darshan_stdio_record *red_recv_buf = NULL;
+ 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
@@ -1203,28 +1041,26 @@ static void stdio_get_output_data(
/* necessary initialization of shared records */
for(i = 0; i < shared_rec_count; i++)
{
- HASH_FIND(hlink, stdio_runtime->file_hash, &shared_recs[i],
- sizeof(darshan_record_id), file);
- assert(file);
+ rec_ref = darshan_lookup_record_ref(stdio_runtime->rec_id_hash,
+ &shared_recs[i], sizeof(darshan_record_id));
+ assert(rec_ref);
- file->file_record->rank = -1;
+ 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
*/
- qsort(stdio_runtime->file_record_array, stdio_runtime->file_array_ndx,
- sizeof(struct darshan_stdio_record), stdio_record_compare);
+ 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_runtime->file_record_array[stdio_runtime->file_array_ndx-shared_rec_count]);
+ 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_record));
+ red_recv_buf = malloc(shared_rec_count * sizeof(struct darshan_stdio_file));
if(!red_recv_buf)
{
return;
@@ -1234,7 +1070,7 @@ static void stdio_get_output_data(
/* 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_record),
+ DARSHAN_MPI_CALL(PMPI_Type_contiguous)(sizeof(struct darshan_stdio_file),
MPI_BYTE, &red_type);
DARSHAN_MPI_CALL(PMPI_Type_commit)(&red_type);
@@ -1248,125 +1084,91 @@ static void stdio_get_output_data(
/* clean up reduction state */
if(my_rank == 0)
{
- int tmp_ndx = stdio_runtime->file_array_ndx - shared_rec_count;
- memcpy(&(stdio_runtime->file_record_array[tmp_ndx]), red_recv_buf,
- shared_rec_count * sizeof(struct darshan_stdio_record));
+ 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_runtime->file_array_ndx -= shared_rec_count;
+ stdio_rec_count -= shared_rec_count;
}
DARSHAN_MPI_CALL(PMPI_Type_free)(&red_type);
DARSHAN_MPI_CALL(PMPI_Op_free)(&red_op);
}
- *stdio_buf = (void *)(stdio_runtime->file_record_array);
- *stdio_buf_sz = stdio_runtime->file_array_ndx * sizeof(struct darshan_stdio_record);
+ /* update output buffer size to account for shared file reduction */
+ *stdio_buf_sz = stdio_rec_count * sizeof(struct darshan_stdio_file);
- return;
-}
-
-/* compare function for sorting file records by descending rank */
-static int stdio_record_compare(const void* a_p, const void* b_p)
-{
- const struct darshan_stdio_record* a = a_p;
- const struct darshan_stdio_record* b = b_p;
+ /* shutdown internal structures used for instrumenting */
+ stdio_cleanup_runtime();
- if(a->rank < b->rank)
- return 1;
- if(a->rank > b->rank)
- return -1;
+ /* disable further instrumentation */
+ instrumentation_disabled = 1;
- return 0;
+ STDIO_UNLOCK();
+
+ return;
}
-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)
{
- struct darshan_stdio_record tmp_file;
- struct darshan_stdio_record *infile = infile_v;
- struct darshan_stdio_record *inoutfile = inoutfile_v;
- int i, j;
+ struct darshan_stdio_file *file_rec = NULL;
+ struct stdio_file_record_ref *rec_ref = NULL;
+ int ret;
- assert(stdio_runtime);
+ rec_ref = malloc(sizeof(*rec_ref));
+ if(!rec_ref)
+ return(NULL);
+ memset(rec_ref, 0, sizeof(*rec_ref));
- for(i=0; i<*len; i++)
+ /* 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)
{
- memset(&tmp_file, 0, sizeof(struct darshan_stdio_record));
- tmp_file.f_id = infile->f_id;
- tmp_file.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];
- }
+ free(rec_ref);
+ return(NULL);
+ }
- /* 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];
- }
+ /* 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_PNETCDF_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);
+ }
- /* 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];
- }
+ /* 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++;
- /* update pointers */
- *inoutfile = tmp_file;
- inoutfile++;
- infile++;
- }
+ return(rec_ref);
- return;
}
-static void stdio_shutdown()
+static void stdio_cleanup_runtime()
{
- struct stdio_file_runtime_ref *ref, *tmp;
+ darshan_clear_record_refs(&(stdio_runtime->stream_hash), 0);
+ darshan_clear_record_refs(&(stdio_runtime->rec_id_hash), 1);
- assert(stdio_runtime);
-
- HASH_ITER(hlink, stdio_runtime->stream_hash, ref, tmp)
- {
- HASH_DELETE(hlink, stdio_runtime->stream_hash, ref);
- free(ref);
- }
-
- HASH_CLEAR(hlink, stdio_runtime->file_hash); /* these entries are freed all at once below */
-
- free(stdio_runtime->file_runtime_array);
- free(stdio_runtime->file_record_array);
free(stdio_runtime);
stdio_runtime = NULL;
- instrumentation_disabled = 0;
-
+
return;
}
=====================================
darshan-stdio-log-format.h
=====================================
--- a/darshan-stdio-log-format.h
+++ b/darshan-stdio-log-format.h
@@ -80,10 +80,9 @@ enum darshan_stdio_f_indices
* - integer I/O counters (operation counts, I/O sizes, etc.)
* - floating point I/O counters (timestamps, cumulative timers, etc.)
*/
-struct darshan_stdio_record
+struct darshan_stdio_file
{
- darshan_record_id f_id;
- int64_t rank;
+ struct darshan_base_record base_rec;
int64_t counters[STDIO_NUM_INDICES];
double fcounters[STDIO_F_NUM_INDICES];
};
View it on GitLab: https://xgitlab.cels.anl.gov/darshan/darshan/commit/ad6ea64f7f18b00e2c778b002ed4fe7731711b32
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.mcs.anl.gov/pipermail/darshan-commits/attachments/20160623/0c67605f/attachment-0001.html>
More information about the Darshan-commits
mailing list