<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html lang="en">
<head>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
<title>
GitLab
</title>

</head>
<body>
<style type="text/css">
img {
max-width: 100%; height: auto;
}
</style>
<div class="content">
<h3>
Shane Snyder pushed to branch mmap-dev
at <a href="https://xgitlab.cels.anl.gov/darshan/darshan">darshan / darshan</a>
</h3>
<h4>
Commits:
</h4>
<ul>
<li>
<strong><a href="https://xgitlab.cels.anl.gov/darshan/darshan/commit/9bfc7b65bb3ed1f77a3dd49e29879d8f95e83e44">9bfc7b65</a></strong>
<div>
<span>by Shane Snyder</span>
<i>at 2016-06-06T17:16:31-05:00</i>
</div>
<pre class="commit-message" style="white-space: pre-wrap">add record_ref interface to darshan-common

This interface provides some convenience functions for mapping
opaque record identifiers (could be a filename, file descriptor,
or any other type of file handle) to a corresponding runtime
structure referencing the actual file record. This runtime
structure should at least contain a pointer to the actual file
record, and can also persist arbitrary state for this record.</pre>
</li>
</ul>
<h4>5 changed files:</h4>
<ul>
<li class="file-stats">
<a href="#620f2ecad2bb6f74b2fcd0134963a841" style="text-decoration: none">
darshan-runtime/darshan-common.h
</a>
</li>
<li class="file-stats">
<a href="#ad29afc395839758d41094872298bd0d" style="text-decoration: none">
darshan-runtime/darshan.h
</a>
</li>
<li class="file-stats">
<a href="#c0b0bf6d71bc5fc7e6d50d69c8aa2413" style="text-decoration: none">
darshan-runtime/lib/darshan-common.c
</a>
</li>
<li class="file-stats">
<a href="#2ace16276b68c7d5aef163bb260bd9f7" style="text-decoration: none">
darshan-runtime/lib/darshan-core.c
</a>
</li>
<li class="file-stats">
<a href="#4dfe7e78b540daa005ea4b5f0458c90d" style="text-decoration: none">
darshan-runtime/lib/darshan-posix.c
</a>
</li>
</ul>
<h4>Changes:</h4>
<li id="620f2ecad2bb6f74b2fcd0134963a841">
<a href="https://xgitlab.cels.anl.gov/darshan/darshan/commit/9bfc7b65bb3ed1f77a3dd49e29879d8f95e83e44#diff-0">
<strong>
darshan-runtime/darshan-common.h
</strong>
</a>
<hr>
<pre class="highlight"><code><span style="background: #ffdddd; color: #000000">--- a/darshan-runtime/darshan-common.h
</span><span style="background: #ddffdd; color: #000000">+++ b/darshan-runtime/darshan-common.h
</span><span style="color: #aaaaaa">@@ -157,6 +157,36 @@ struct darshan_variance_dt
</span> * darshan-common functions for darshan modules *
 ***********************************************/
 
<span style="background: #ddffdd; color: #000000">+void *darshan_lookup_record_ref(
+    void *hash_head,
+    void *handle,
+    size_t handle_sz);
+
+int darshan_add_record_ref(
+    void **hash_head,
+    void *handle,
+    size_t handle_sz,
+    void *rec_ref_p);
+
+void *darshan_delete_record_ref(
+    void **hash_head,
+    void *handle,
+    size_t handle_sz);
+
+void darshan_clear_record_refs(
+    void **hash_head,    
+    int free_flag);
+
+void darshan_iter_record_refs(
+    void *hash_head,
+    void (*iter_action)(void *));
+
+darshan_record_id darshan_record_id_from_path(
+    const char *path);
+
+darshan_record_id darshan_record_id_from_name(
+    const char *name);
+
</span> /* darshan_clean_file_path()
  *
  * Allocate a new string that contains a new cleaned-up version of
</code></pre>

<br>
</li>
<li id="ad29afc395839758d41094872298bd0d">
<a href="https://xgitlab.cels.anl.gov/darshan/darshan/commit/9bfc7b65bb3ed1f77a3dd49e29879d8f95e83e44#diff-1">
<strong>
darshan-runtime/darshan.h
</strong>
</a>
<hr>
<pre class="highlight"><code><span style="background: #ffdddd; color: #000000">--- a/darshan-runtime/darshan.h
</span><span style="background: #ddffdd; color: #000000">+++ b/darshan-runtime/darshan.h
</span><span style="color: #aaaaaa">@@ -118,7 +118,7 @@ void darshan_core_unregister_module(
</span>  *
  */
 darshan_record_id darshan_core_gen_record_id(
<span style="background: #ffdddd; color: #000000">-    char *name);
</span><span style="background: #ddffdd; color: #000000">+    const char *name);
</span> 
 /* darshan_core_register_record()
  *
<span style="color: #aaaaaa">@@ -136,7 +136,7 @@ darshan_record_id darshan_core_gen_record_id(
</span>  */
 void *darshan_core_register_record(
     darshan_record_id rec_id,
<span style="background: #ffdddd; color: #000000">-    char *name,
</span><span style="background: #ddffdd; color: #000000">+    const char *name,
</span>     darshan_module_id mod_id,
     int rec_len,
     int *file_alignment);
</code></pre>

<br>
</li>
<li id="c0b0bf6d71bc5fc7e6d50d69c8aa2413">
<a href="https://xgitlab.cels.anl.gov/darshan/darshan/commit/9bfc7b65bb3ed1f77a3dd49e29879d8f95e83e44#diff-2">
<strong>
darshan-runtime/lib/darshan-common.c
</strong>
</a>
<hr>
<pre class="highlight"><code><span style="background: #ffdddd; color: #000000">--- a/darshan-runtime/lib/darshan-common.c
</span><span style="background: #ddffdd; color: #000000">+++ b/darshan-runtime/lib/darshan-common.c
</span><span style="color: #aaaaaa">@@ -15,11 +15,122 @@
</span> #include <search.h>
 #include <assert.h>
 
<span style="background: #ddffdd; color: #000000">+#include "uthash.h"
+
</span> #include "darshan.h"
 
<span style="background: #ffdddd; color: #000000">-static int darshan_common_val_compare(const void* a_p, const void* b_p);
-static void darshan_common_val_walker(const void* nodep, const VISIT which,
-    const int depth);
</span><span style="background: #ddffdd; color: #000000">+
+struct darshan_record_ref_tracker
+{
+    void *rec_ref_p;
+    UT_hash_handle hlink;
+};
+
+void *darshan_lookup_record_ref(void *hash_head, void *handle, size_t handle_sz)
+{
+    struct darshan_record_ref_tracker *ref_tracker;
+    struct darshan_record_ref_tracker *ref_tracker_head =
+        (struct darshan_record_ref_tracker *)hash_head;
+
+    HASH_FIND(hlink, ref_tracker_head, handle, handle_sz, ref_tracker);
+    if(ref_tracker)
+        return(ref_tracker->rec_ref_p);
+    else
+        return(NULL);
+}
+
+int darshan_add_record_ref(void **hash_head, void *handle, size_t handle_sz,
+    void *rec_ref_p)
+{
+    struct darshan_record_ref_tracker *ref_tracker;
+    struct darshan_record_ref_tracker *ref_tracker_head =
+        *(struct darshan_record_ref_tracker **)hash_head;
+    void *handle_p;
+
+    ref_tracker = malloc(sizeof(*ref_tracker) + handle_sz);
+    if(!ref_tracker)
+        return(0);
+    memset(ref_tracker, 0, sizeof(*ref_tracker) + handle_sz);
+
+    ref_tracker->rec_ref_p = rec_ref_p;
+    handle_p = (char *)ref_tracker + sizeof(*ref_tracker);
+    memcpy(handle_p, handle, handle_sz);
+    HASH_ADD_KEYPTR(hlink, ref_tracker_head, handle_p, handle_sz, ref_tracker);
+    *hash_head = ref_tracker_head;
+    return(1);
+}
+
+void *darshan_delete_record_ref(void **hash_head, void *handle, size_t handle_sz)
+{
+    struct darshan_record_ref_tracker *ref_tracker;
+    struct darshan_record_ref_tracker *ref_tracker_head =
+        *(struct darshan_record_ref_tracker **)hash_head;
+    void *rec_ref_p;
+
+    HASH_FIND(hlink, ref_tracker_head, handle, handle_sz, ref_tracker);
+    if(!ref_tracker)
+        return(NULL);
+
+    HASH_DELETE(hlink, ref_tracker_head, ref_tracker);
+    *hash_head = ref_tracker_head;
+    rec_ref_p = ref_tracker->rec_ref_p;
+    free(ref_tracker);
+
+    return(rec_ref_p);
+}
+
+void darshan_clear_record_refs(void **hash_head, int free_flag)
+{
+    struct darshan_record_ref_tracker *ref_tracker, *tmp;
+    struct darshan_record_ref_tracker *ref_tracker_head =
+        *(struct darshan_record_ref_tracker **)hash_head;
+
+    HASH_ITER(hlink, ref_tracker_head, ref_tracker, tmp)
+    {
+        HASH_DELETE(hlink, ref_tracker_head, ref_tracker);
+        if(free_flag)
+            free(ref_tracker->rec_ref_p);
+        free(ref_tracker);
+    }
+    *hash_head = ref_tracker_head;
+
+    return;
+}
+
+void darshan_iter_record_refs(void *hash_head, void (*iter_action)(void *))
+{
+    struct darshan_record_ref_tracker *ref_tracker, *tmp;
+    struct darshan_record_ref_tracker *ref_tracker_head =
+        (struct darshan_record_ref_tracker *)hash_head;
+
+    HASH_ITER(hlink, ref_tracker_head, ref_tracker, tmp)
+    {
+        iter_action(ref_tracker->rec_ref_p);
+    }
+
+    return;
+}
+
+darshan_record_id darshan_record_id_from_path(const char *path)
+{
+    char *newpath = NULL;
+    darshan_record_id rec_id;
+
+    newpath = darshan_clean_file_path(path);
+    if(!newpath)
+        newpath = (char *)path;
+
+    rec_id = darshan_record_id_from_name(newpath);
+
+    if(newpath != path)
+        free(newpath);
+    return(rec_id);
+}
+
+darshan_record_id darshan_record_id_from_name(const char *name)
+{
+    return(darshan_core_gen_record_id(name));
+}
</span> 
 char* darshan_clean_file_path(const char* path)
 {
<span style="color: #aaaaaa">@@ -82,6 +193,37 @@ char* darshan_clean_file_path(const char* path)
</span> static int64_t* walker_val_p = NULL;
 static int64_t* walker_cnt_p = NULL;
 
<span style="background: #ddffdd; color: #000000">+static void darshan_common_val_walker(const void *nodep, const VISIT which,
+    const int depth)
+{
+    struct darshan_common_val_counter* counter;
+
+    switch (which)
+    {
+        case postorder:
+        case leaf:
+            counter = *(struct darshan_common_val_counter**)nodep;
+            DARSHAN_COMMON_VAL_COUNTER_INC(walker_val_p, walker_cnt_p,
+                counter->val, counter->freq, 0);
+        default:
+            break;
+    }
+
+    return;
+}
+
+static int darshan_common_val_compare(const void *a_p, const void *b_p)
+{
+    const struct darshan_common_val_counter* a = a_p;
+    const struct darshan_common_val_counter* b = b_p;
+
+    if(a->val < b->val)
+        return(-1);
+    if(a->val > b->val)
+        return(1);
+    return(0);
+}
+
</span> void darshan_common_val_counter(void **common_val_root, int *common_val_count,
     int64_t val, int64_t *common_val_p, int64_t *common_cnt_p)
 {
<span style="color: #aaaaaa">@@ -146,37 +288,6 @@ void darshan_walk_common_vals(void *common_val_root, int64_t *val_p,
</span>     return;
 }
 
<span style="background: #ffdddd; color: #000000">-static void darshan_common_val_walker(const void *nodep, const VISIT which,
-    const int depth)
-{
-    struct darshan_common_val_counter* counter;
-
-    switch (which)
-    {
-        case postorder:
-        case leaf:
-            counter = *(struct darshan_common_val_counter**)nodep;
-            DARSHAN_COMMON_VAL_COUNTER_INC(walker_val_p, walker_cnt_p,
-                counter->val, counter->freq, 0);
-        default:
-            break;
-    }
-
-    return;
-}
-
-static int darshan_common_val_compare(const void *a_p, const void *b_p)
-{
-    const struct darshan_common_val_counter* a = a_p;
-    const struct darshan_common_val_counter* b = b_p;
-
-    if(a->val < b->val)
-        return(-1);
-    if(a->val > b->val)
-        return(1);
-    return(0);
-}
-
</span> void darshan_variance_reduce(void *invec, void *inoutvec, int *len,
     MPI_Datatype *dt)
 {
</code></pre>

<br>
</li>
<li id="2ace16276b68c7d5aef163bb260bd9f7">
<a href="https://xgitlab.cels.anl.gov/darshan/darshan/commit/9bfc7b65bb3ed1f77a3dd49e29879d8f95e83e44#diff-3">
<strong>
darshan-runtime/lib/darshan-core.c
</strong>
</a>
<hr>
<pre class="highlight"><code><span style="background: #ffdddd; color: #000000">--- a/darshan-runtime/lib/darshan-core.c
</span><span style="background: #ddffdd; color: #000000">+++ b/darshan-runtime/lib/darshan-core.c
</span><span style="color: #aaaaaa">@@ -95,7 +95,7 @@ static void darshan_get_exe_and_mounts(
</span>     struct darshan_core_runtime *core, int argc, char **argv);
 static void darshan_add_name_record_ref(
     struct darshan_core_runtime *core, darshan_record_id rec_id,
<span style="background: #ffdddd; color: #000000">-    char *name, darshan_module_id mod_id);
</span><span style="background: #ddffdd; color: #000000">+    const char *name, darshan_module_id mod_id);
</span> static int darshan_block_size_from_path(
     const char *path);
 static void darshan_get_user_name(
<span style="color: #aaaaaa">@@ -1222,7 +1222,7 @@ static void darshan_get_logfile_name(char* logfile_name, int jobid, struct tm* s
</span> }
 
 static void darshan_add_name_record_ref(struct darshan_core_runtime *core,
<span style="background: #ffdddd; color: #000000">-    darshan_record_id rec_id, char *name, darshan_module_id mod_id)
</span><span style="background: #ddffdd; color: #000000">+    darshan_record_id rec_id, const char *name, darshan_module_id mod_id)
</span> {
     struct darshan_core_name_record_ref *ref;
     int record_size = sizeof(darshan_record_id) + strlen(name) + 1;
<span style="color: #aaaaaa">@@ -1778,7 +1778,7 @@ void darshan_core_unregister_module(
</span> }
 
 darshan_record_id darshan_core_gen_record_id(
<span style="background: #ffdddd; color: #000000">-    char *name)
</span><span style="background: #ddffdd; color: #000000">+    const char *name)
</span> {
     /* hash the input name to get a unique id for this record */
     return darshan_hash((unsigned char *)name, strlen(name), 0);
<span style="color: #aaaaaa">@@ -1786,7 +1786,7 @@ darshan_record_id darshan_core_gen_record_id(
</span> 
 void *darshan_core_register_record(
     darshan_record_id rec_id,
<span style="background: #ffdddd; color: #000000">-    char *name,
</span><span style="background: #ddffdd; color: #000000">+    const char *name,
</span>     darshan_module_id mod_id,
     int rec_len,
     int *file_alignment)
</code></pre>

<br>
</li>
<li id="4dfe7e78b540daa005ea4b5f0458c90d">
<a href="https://xgitlab.cels.anl.gov/darshan/darshan/commit/9bfc7b65bb3ed1f77a3dd49e29879d8f95e83e44#diff-4">
<strong>
darshan-runtime/lib/darshan-posix.c
</strong>
</a>
<hr>
<pre class="highlight"><code><span style="background: #ffdddd; color: #000000">--- a/darshan-runtime/lib/darshan-posix.c
</span><span style="background: #ddffdd; color: #000000">+++ b/darshan-runtime/lib/darshan-posix.c
</span><span style="color: #aaaaaa">@@ -26,7 +26,6 @@
</span> #include <aio.h>
 #include <pthread.h>
 
<span style="background: #ffdddd; color: #000000">-#include "uthash.h"
</span> #include "utlist.h"
 
 #include "darshan.h"
<span style="color: #aaaaaa">@@ -91,32 +90,9 @@ struct posix_aio_tracker
</span>     struct posix_aio_tracker* next;
 };
 
<span style="background: #ffdddd; color: #000000">-/* The posix_file_runtime structure maintains necessary runtime metadata
- * for the POSIX file record (darshan_posix_file structure, defined in
- * darshan-posix-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 POSIX file records for this process. 
- *
- * RATIONALE: the POSIX 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_posix_file struct because we don't want it to appear in
- * the final darshan log file.  We therefore associate a posix_file_runtime
- * struct with each darshan_posix_file struct in order to track this information.
-  *
- * NOTE: There is a one-to-one mapping of posix_file_runtime structs to
- * darshan_posix_file structs.
- *
- * NOTE: The posix_file_runtime struct contains a pointer to a darshan_posix_file
- * struct (see the *file_record member) rather than simply embedding an entire
- * darshan_posix_file struct.  This is done so that all of the darshan_posix_file
- * structs can be kept contiguous in memory as a single array to simplify
- * reduction, compression, and storage.
- */
-struct posix_file_runtime
</span><span style="background: #ddffdd; color: #000000">+struct posix_file_record_ref
</span> {
<span style="background: #ffdddd; color: #000000">-    struct darshan_posix_file* file_record;
</span><span style="background: #ddffdd; color: #000000">+    struct darshan_posix_file* file_rec;
</span>     int64_t offset;
     int64_t last_byte_read;
     int64_t last_byte_written;
<span style="color: #aaaaaa">@@ -129,47 +105,13 @@ struct posix_file_runtime
</span>     void* stride_root;
     int stride_count;
     struct posix_aio_tracker* aio_list;
<span style="background: #ffdddd; color: #000000">-    UT_hash_handle hlink;
-};
-
-/* The posix_file_runtime_ref structure is used to associate a POSIX
- * file descriptor with an already existing POSIX file record. This is
- * necessary as many POSIX I/O functions take only an input file descriptor,
- * but POSIX file records are indexed by their full file paths (i.e., darshan
- * record identifiers for POSIX 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 (posix_file_runtime) or by POSIX file
- * descriptor (posix_file_runtime_ref), depending on which parameters are
- * available. This structure includes another hash table link, since separate
- * hashes are maintained for posix_file_runtime structures and posix_file_runtime_ref
- * structures.
- *
- * RATIONALE: In theory the fd information could be included in the
- * posix_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 file descriptors and thus
- * simulataneously referenced using different file descriptors.  This practice is
- * not common, but we must support it.
- *
- * NOTE: there are potentially multiple posix_file_runtime_ref structures
- * referring to a single posix_file_runtime structure.  Most of the time there is
- * only one, however.
- */
-struct posix_file_runtime_ref
-{
-    struct posix_file_runtime* file;
-    int fd;
-    UT_hash_handle hlink;
</span> };
 
<span style="background: #ffdddd; color: #000000">-/* The posix_runtime structure maintains necessary state for storing
- * POSIX file records and for coordinating with darshan-core at 
- * shutdown time.
- */
</span> struct posix_runtime
 {
<span style="background: #ffdddd; color: #000000">-    struct posix_file_runtime* file_hash;
-    struct posix_file_runtime_ref* fd_hash;
</span><span style="background: #ddffdd; color: #000000">+    void *rec_id_hash;
+    void *fd_hash;
+    int file_rec_count;
</span> };
 
 static struct posix_runtime *posix_runtime = NULL;
<span style="color: #aaaaaa">@@ -178,175 +120,194 @@ static int instrumentation_disabled = 0;
</span> static int my_rank = -1;
 static int darshan_mem_alignment = 1;
 
<span style="background: #ffdddd; color: #000000">-static void posix_runtime_initialize(void);
-static struct posix_file_runtime* posix_file_by_name(const char *name);
-static struct posix_file_runtime* posix_file_by_name_setfd(const char* name, int fd);
-static struct posix_file_runtime* posix_file_by_fd(int fd);
-static void posix_file_close_fd(int fd);
-static void posix_aio_tracker_add(int fd, void *aiocbp);
-static struct posix_aio_tracker* posix_aio_tracker_del(int fd, void *aiocbp);
-static int posix_record_compare(const void* a, const void* b);
-static void posix_record_reduction_op(void* infile_v, void* inoutfile_v,
-    int *len, MPI_Datatype *datatype);
-static void posix_shared_record_variance(MPI_Comm mod_comm,
-    struct darshan_posix_file *inrec_array, struct darshan_posix_file *outrec_array,
-    int shared_rec_count);
-
-static void posix_begin_shutdown(void);
-static void posix_get_output_data(MPI_Comm mod_comm, darshan_record_id *shared_recs,
</span><span style="background: #ddffdd; color: #000000">+static void posix_runtime_initialize(
+    void);
+static struct posix_file_record_ref *posix_track_new_file_record(
+    darshan_record_id rec_id, const char *path);
+static void posix_aio_tracker_add(
+    int fd, void *aiocbp);
+static struct posix_aio_tracker* posix_aio_tracker_del(
+    int fd, void *aiocbp);
+static int posix_record_compare(
+    const void* a, const void* b);
+static void posix_record_reduction_op(
+    void* infile_v, void* inoutfile_v, int *len, MPI_Datatype *datatype);
+static void posix_shared_record_variance(
+    MPI_Comm mod_comm, struct darshan_posix_file *inrec_array,
+    struct darshan_posix_file *outrec_array, int shared_rec_count);
+
+static void posix_begin_shutdown(
+    void);
+static void posix_get_output_data(
+    MPI_Comm mod_comm, darshan_record_id *shared_recs,
</span>     int shared_rec_count, void **posix_buf, int *posix_buf_sz);
<span style="background: #ffdddd; color: #000000">-static void posix_shutdown(void);
</span><span style="background: #ddffdd; color: #000000">+static void posix_shutdown(
+    void);
</span> 
 #define POSIX_LOCK() pthread_mutex_lock(&posix_runtime_mutex)
 #define POSIX_UNLOCK() pthread_mutex_unlock(&posix_runtime_mutex)
 
 #define POSIX_RECORD_OPEN(__ret, __path, __mode, __stream_flag, __tm1, __tm2) do { \
<span style="background: #ffdddd; color: #000000">-    struct posix_file_runtime* file; \
</span><span style="background: #ddffdd; color: #000000">+    struct posix_file_record_ref *rec_ref; \
+    darshan_record_id rec_id; \
</span>     if(__ret < 0) break; \
<span style="background: #ddffdd; color: #000000">+    if(!posix_runtime || instrumentation_disabled) break; /* XXX: PREMABLE??? */\
</span>     if(darshan_core_excluded_path(__path)) break; \
<span style="background: #ffdddd; color: #000000">-    file = posix_file_by_name_setfd(__path, __ret); \
-    if(!file) break; \
</span><span style="background: #ddffdd; color: #000000">+    rec_id = darshan_record_id_from_path(__path); \
+    rec_ref = darshan_lookup_record_ref(posix_runtime->rec_id_hash, &rec_id, sizeof(darshan_record_id)); \
+    if(!rec_ref) { \
+        rec_ref = posix_track_new_file_record(rec_id, __path); \
+        if(!rec_ref) break; \
+    } \
+    if(darshan_add_record_ref(&(posix_runtime->fd_hash), &__ret, sizeof(int), rec_ref) == 0) break; \
</span>     if(__mode) \
<span style="background: #ffdddd; color: #000000">-        file->file_record->counters[POSIX_MODE] = __mode; \
-    file->offset = 0; \
-    file->last_byte_written = 0; \
-    file->last_byte_read = 0; \
</span><span style="background: #ddffdd; color: #000000">+        rec_ref->file_rec->counters[POSIX_MODE] = __mode; \
+    rec_ref->offset = 0; \
+    rec_ref->last_byte_written = 0; \
+    rec_ref->last_byte_read = 0; \
</span>     if(__stream_flag)\
<span style="background: #ffdddd; color: #000000">-        file->file_record->counters[POSIX_FOPENS] += 1; \
</span><span style="background: #ddffdd; color: #000000">+        rec_ref->file_rec->counters[POSIX_FOPENS] += 1; \
</span>     else \
<span style="background: #ffdddd; color: #000000">-        file->file_record->counters[POSIX_OPENS] += 1; \
-    if(file->file_record->fcounters[POSIX_F_OPEN_TIMESTAMP] == 0) \
-        file->file_record->fcounters[POSIX_F_OPEN_TIMESTAMP] = __tm1; \
-    DARSHAN_TIMER_INC_NO_OVERLAP(file->file_record->fcounters[POSIX_F_META_TIME], \
-        __tm1, __tm2, file->last_meta_end); \
</span><span style="background: #ddffdd; color: #000000">+        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; \
+    DARSHAN_TIMER_INC_NO_OVERLAP(rec_ref->file_rec->fcounters[POSIX_F_META_TIME], \
+        __tm1, __tm2, rec_ref->last_meta_end); \
</span> } while(0)
 
<span style="background: #ffdddd; color: #000000">-#define POSIX_RECORD_READ(__ret, __fd, __pread_flag, __pread_offset, __aligned, __stream_flag, __tm1, __tm2) do{ \
</span><span style="background: #ddffdd; color: #000000">+#define POSIX_RECORD_READ(__ret, __fd, __pread_flag, __pread_offset, __aligned, __stream_flag, __tm1, __tm2) do { \
+    struct posix_file_record_ref* rec_ref; \
</span>     size_t stride; \
     int64_t this_offset; \
<span style="background: #ffdddd; color: #000000">-    struct posix_file_runtime* file; \
</span>     int64_t file_alignment; \
     double __elapsed = __tm2-__tm1; \
     if(__ret < 0) break; \
<span style="background: #ffdddd; color: #000000">-    file = posix_file_by_fd(__fd); \
-    if(!file) break; \
</span><span style="background: #ddffdd; color: #000000">+    if(!posix_runtime || instrumentation_disabled) break; /* XXX: PREMABLE??? */\
+    rec_ref = darshan_lookup_record_ref(posix_runtime->fd_hash, &(__fd), sizeof(int)); \
+    if(!rec_ref) break; \
</span>     if(__pread_flag) \
         this_offset = __pread_offset; \
     else \
<span style="background: #ffdddd; color: #000000">-        this_offset = file->offset; \
-    if(this_offset > file->last_byte_read) \
-        file->file_record->counters[POSIX_SEQ_READS] += 1;  \
-    if(this_offset == (file->last_byte_read + 1)) \
-        file->file_record->counters[POSIX_CONSEC_READS] += 1;  \
-    if(this_offset > 0 && this_offset > file->last_byte_read \
-        && file->last_byte_read != 0) \
-        stride = this_offset - file->last_byte_read - 1; \
</span><span style="background: #ddffdd; color: #000000">+        this_offset = rec_ref->offset; \
+    if(this_offset > rec_ref->last_byte_read) \
+        rec_ref->file_rec->counters[POSIX_SEQ_READS] += 1;  \
+    if(this_offset == (rec_ref->last_byte_read + 1)) \
+        rec_ref->file_rec->counters[POSIX_CONSEC_READS] += 1;  \
+    if(this_offset > 0 && this_offset > rec_ref->last_byte_read \
+        && rec_ref->last_byte_read != 0) \
+        stride = this_offset - rec_ref->last_byte_read - 1; \
</span>     else \
         stride = 0; \
<span style="background: #ffdddd; color: #000000">-    file->last_byte_read = this_offset + __ret - 1; \
-    file->offset = this_offset + __ret; \
-    if(file->file_record->counters[POSIX_MAX_BYTE_READ] < (this_offset + __ret - 1)) \
-        file->file_record->counters[POSIX_MAX_BYTE_READ] = (this_offset + __ret - 1); \
-    file->file_record->counters[POSIX_BYTES_READ] += __ret; \
</span><span style="background: #ddffdd; color: #000000">+    rec_ref->last_byte_read = this_offset + __ret - 1; \
+    rec_ref->offset = this_offset + __ret; \
+    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; \
</span>     if(__stream_flag) \
<span style="background: #ffdddd; color: #000000">-        file->file_record->counters[POSIX_FREADS] += 1; \
</span><span style="background: #ddffdd; color: #000000">+        rec_ref->file_rec->counters[POSIX_FREADS] += 1; \
</span>     else \
<span style="background: #ffdddd; color: #000000">-        file->file_record->counters[POSIX_READS] += 1; \
-    DARSHAN_BUCKET_INC(&(file->file_record->counters[POSIX_SIZE_READ_0_100]), __ret); \
-    darshan_common_val_counter(&file->access_root, &file->access_count, __ret, \
-        &(file->file_record->counters[POSIX_ACCESS1_ACCESS]), \
-        &(file->file_record->counters[POSIX_ACCESS1_COUNT])); \
-    darshan_common_val_counter(&file->stride_root, &file->stride_count, stride, \
-        &(file->file_record->counters[POSIX_STRIDE1_STRIDE]), \
-        &(file->file_record->counters[POSIX_STRIDE1_COUNT])); \
</span><span style="background: #ddffdd; color: #000000">+        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]), \
+        &(rec_ref->file_rec->counters[POSIX_ACCESS1_COUNT])); \
+    darshan_common_val_counter(&rec_ref->stride_root, &rec_ref->stride_count, stride, \
+        &(rec_ref->file_rec->counters[POSIX_STRIDE1_STRIDE]), \
+        &(rec_ref->file_rec->counters[POSIX_STRIDE1_COUNT])); \
</span>     if(!__aligned) \
<span style="background: #ffdddd; color: #000000">-        file->file_record->counters[POSIX_MEM_NOT_ALIGNED] += 1; \
-    file_alignment = file->file_record->counters[POSIX_FILE_ALIGNMENT]; \
</span><span style="background: #ddffdd; color: #000000">+        rec_ref->file_rec->counters[POSIX_MEM_NOT_ALIGNED] += 1; \
+    file_alignment = rec_ref->file_rec->counters[POSIX_FILE_ALIGNMENT]; \
</span>     if(file_alignment > 0 && (this_offset % file_alignment) != 0) \
<span style="background: #ffdddd; color: #000000">-        file->file_record->counters[POSIX_FILE_NOT_ALIGNED] += 1; \
-    if(file->last_io_type == DARSHAN_IO_WRITE) \
-        file->file_record->counters[POSIX_RW_SWITCHES] += 1; \
-    file->last_io_type = DARSHAN_IO_READ; \
-    if(file->file_record->fcounters[POSIX_F_READ_START_TIMESTAMP] == 0) \
-        file->file_record->fcounters[POSIX_F_READ_START_TIMESTAMP] = __tm1; \
-    file->file_record->fcounters[POSIX_F_READ_END_TIMESTAMP] = __tm2; \
-    if(file->file_record->fcounters[POSIX_F_MAX_READ_TIME] < __elapsed) { \
-        file->file_record->fcounters[POSIX_F_MAX_READ_TIME] = __elapsed; \
-        file->file_record->counters[POSIX_MAX_READ_TIME_SIZE] = __ret; } \
-    DARSHAN_TIMER_INC_NO_OVERLAP(file->file_record->fcounters[POSIX_F_READ_TIME], \
-        __tm1, __tm2, file->last_read_end); \
</span><span style="background: #ddffdd; color: #000000">+        rec_ref->file_rec->counters[POSIX_FILE_NOT_ALIGNED] += 1; \
+    if(rec_ref->last_io_type == DARSHAN_IO_WRITE) \
+        rec_ref->file_rec->counters[POSIX_RW_SWITCHES] += 1; \
+    rec_ref->last_io_type = DARSHAN_IO_READ; \
+    if(rec_ref->file_rec->fcounters[POSIX_F_READ_START_TIMESTAMP] == 0) \
+        rec_ref->file_rec->fcounters[POSIX_F_READ_START_TIMESTAMP] = __tm1; \
+    rec_ref->file_rec->fcounters[POSIX_F_READ_END_TIMESTAMP] = __tm2; \
+    if(rec_ref->file_rec->fcounters[POSIX_F_MAX_READ_TIME] < __elapsed) { \
+        rec_ref->file_rec->fcounters[POSIX_F_MAX_READ_TIME] = __elapsed; \
+        rec_ref->file_rec->counters[POSIX_MAX_READ_TIME_SIZE] = __ret; } \
+    DARSHAN_TIMER_INC_NO_OVERLAP(rec_ref->file_rec->fcounters[POSIX_F_READ_TIME], \
+        __tm1, __tm2, rec_ref->last_read_end); \
</span> } while(0)
 
<span style="background: #ffdddd; color: #000000">-#define POSIX_RECORD_WRITE(__ret, __fd, __pwrite_flag, __pwrite_offset, __aligned, __stream_flag, __tm1, __tm2) do{ \
</span><span style="background: #ddffdd; color: #000000">+#define POSIX_RECORD_WRITE(__ret, __fd, __pwrite_flag, __pwrite_offset, __aligned, __stream_flag, __tm1, __tm2) do { \
+    struct posix_file_record_ref* rec_ref; \
</span>     size_t stride; \
     int64_t this_offset; \
<span style="background: #ffdddd; color: #000000">-    struct posix_file_runtime* file; \
</span>     int64_t file_alignment; \
     double __elapsed = __tm2-__tm1; \
     if(__ret < 0) break; \
<span style="background: #ffdddd; color: #000000">-    file = posix_file_by_fd(__fd); \
-    if(!file) break; \
</span><span style="background: #ddffdd; color: #000000">+    if(!posix_runtime || instrumentation_disabled) break; /* XXX: PREMABLE??? */\
+    rec_ref = darshan_lookup_record_ref(posix_runtime->fd_hash, &__fd, sizeof(int)); \
+    if(!rec_ref) break; \
</span>     if(__pwrite_flag) \
         this_offset = __pwrite_offset; \
     else \
<span style="background: #ffdddd; color: #000000">-        this_offset = file->offset; \
-    if(this_offset > file->last_byte_written) \
-        file->file_record->counters[POSIX_SEQ_WRITES] += 1; \
-    if(this_offset == (file->last_byte_written + 1)) \
-        file->file_record->counters[POSIX_CONSEC_WRITES] += 1; \
-    if(this_offset > 0 && this_offset > file->last_byte_written \
-        && file->last_byte_written != 0) \
-        stride = this_offset - file->last_byte_written - 1; \
</span><span style="background: #ddffdd; color: #000000">+        this_offset = rec_ref->offset; \
+    if(this_offset > rec_ref->last_byte_written) \
+        rec_ref->file_rec->counters[POSIX_SEQ_WRITES] += 1; \
+    if(this_offset == (rec_ref->last_byte_written + 1)) \
+        rec_ref->file_rec->counters[POSIX_CONSEC_WRITES] += 1; \
+    if(this_offset > 0 && this_offset > rec_ref->last_byte_written \
+        && rec_ref->last_byte_written != 0) \
+        stride = this_offset - rec_ref->last_byte_written - 1; \
</span>     else \
         stride = 0; \
<span style="background: #ffdddd; color: #000000">-    file->last_byte_written = this_offset + __ret - 1; \
-    file->offset = this_offset + __ret; \
-    if(file->file_record->counters[POSIX_MAX_BYTE_WRITTEN] < (this_offset + __ret - 1)) \
-        file->file_record->counters[POSIX_MAX_BYTE_WRITTEN] = (this_offset + __ret - 1); \
-    file->file_record->counters[POSIX_BYTES_WRITTEN] += __ret; \
</span><span style="background: #ddffdd; color: #000000">+    rec_ref->last_byte_written = this_offset + __ret - 1; \
+    rec_ref->offset = this_offset + __ret; \
+    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; \
</span>     if(__stream_flag) \
<span style="background: #ffdddd; color: #000000">-        file->file_record->counters[POSIX_FWRITES] += 1; \
</span><span style="background: #ddffdd; color: #000000">+        rec_ref->file_rec->counters[POSIX_FWRITES] += 1; \
</span>     else \
<span style="background: #ffdddd; color: #000000">-        file->file_record->counters[POSIX_WRITES] += 1; \
-    DARSHAN_BUCKET_INC(&(file->file_record->counters[POSIX_SIZE_WRITE_0_100]), __ret); \
-    darshan_common_val_counter(&file->access_root, &file->access_count, __ret, \
-        &(file->file_record->counters[POSIX_ACCESS1_ACCESS]), \
-        &(file->file_record->counters[POSIX_ACCESS1_COUNT])); \
-    darshan_common_val_counter(&file->stride_root, &file->stride_count, stride, \
-        &(file->file_record->counters[POSIX_STRIDE1_STRIDE]), \
-        &(file->file_record->counters[POSIX_STRIDE1_COUNT])); \
</span><span style="background: #ddffdd; color: #000000">+        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]), \
+        &(rec_ref->file_rec->counters[POSIX_ACCESS1_COUNT])); \
+    darshan_common_val_counter(&rec_ref->stride_root, &rec_ref->stride_count, stride, \
+        &(rec_ref->file_rec->counters[POSIX_STRIDE1_STRIDE]), \
+        &(rec_ref->file_rec->counters[POSIX_STRIDE1_COUNT])); \
</span>     if(!__aligned) \
<span style="background: #ffdddd; color: #000000">-        file->file_record->counters[POSIX_MEM_NOT_ALIGNED] += 1; \
-    file_alignment = file->file_record->counters[POSIX_FILE_ALIGNMENT]; \
</span><span style="background: #ddffdd; color: #000000">+        rec_ref->file_rec->counters[POSIX_MEM_NOT_ALIGNED] += 1; \
+    file_alignment = rec_ref->file_rec->counters[POSIX_FILE_ALIGNMENT]; \
</span>     if(file_alignment > 0 && (this_offset % file_alignment) != 0) \
<span style="background: #ffdddd; color: #000000">-        file->file_record->counters[POSIX_FILE_NOT_ALIGNED] += 1; \
-    if(file->last_io_type == DARSHAN_IO_READ) \
-        file->file_record->counters[POSIX_RW_SWITCHES] += 1; \
-    file->last_io_type = DARSHAN_IO_WRITE; \
-    if(file->file_record->fcounters[POSIX_F_WRITE_START_TIMESTAMP] == 0) \
-        file->file_record->fcounters[POSIX_F_WRITE_START_TIMESTAMP] = __tm1; \
-    file->file_record->fcounters[POSIX_F_WRITE_END_TIMESTAMP] = __tm2; \
-    if(file->file_record->fcounters[POSIX_F_MAX_WRITE_TIME] < __elapsed) { \
-        file->file_record->fcounters[POSIX_F_MAX_WRITE_TIME] = __elapsed; \
-        file->file_record->counters[POSIX_MAX_WRITE_TIME_SIZE] = __ret; } \
-    DARSHAN_TIMER_INC_NO_OVERLAP(file->file_record->fcounters[POSIX_F_WRITE_TIME], \
-        __tm1, __tm2, file->last_write_end); \
</span><span style="background: #ddffdd; color: #000000">+        rec_ref->file_rec->counters[POSIX_FILE_NOT_ALIGNED] += 1; \
+    if(rec_ref->last_io_type == DARSHAN_IO_READ) \
+        rec_ref->file_rec->counters[POSIX_RW_SWITCHES] += 1; \
+    rec_ref->last_io_type = DARSHAN_IO_WRITE; \
+    if(rec_ref->file_rec->fcounters[POSIX_F_WRITE_START_TIMESTAMP] == 0) \
+        rec_ref->file_rec->fcounters[POSIX_F_WRITE_START_TIMESTAMP] = __tm1; \
+    rec_ref->file_rec->fcounters[POSIX_F_WRITE_END_TIMESTAMP] = __tm2; \
+    if(rec_ref->file_rec->fcounters[POSIX_F_MAX_WRITE_TIME] < __elapsed) { \
+        rec_ref->file_rec->fcounters[POSIX_F_MAX_WRITE_TIME] = __elapsed; \
+        rec_ref->file_rec->counters[POSIX_MAX_WRITE_TIME_SIZE] = __ret; } \
+    DARSHAN_TIMER_INC_NO_OVERLAP(rec_ref->file_rec->fcounters[POSIX_F_WRITE_TIME], \
+        __tm1, __tm2, rec_ref->last_write_end); \
</span> } while(0)
 
 #define POSIX_LOOKUP_RECORD_STAT(__path, __statbuf, __tm1, __tm2) do { \
<span style="background: #ffdddd; color: #000000">-    struct posix_file_runtime* file; \
</span><span style="background: #ddffdd; color: #000000">+    struct posix_file_record_ref* rec_ref; \
+    darshan_record_id rec_id; \
+    if(!posix_runtime || instrumentation_disabled) break; /* XXX: PREMABLE??? */\
</span>     if(darshan_core_excluded_path(__path)) break; \
<span style="background: #ffdddd; color: #000000">-    file = posix_file_by_name(__path); \
-    if(file) \
-    { \
-        POSIX_RECORD_STAT(file, __statbuf, __tm1, __tm2); \
</span><span style="background: #ddffdd; color: #000000">+    rec_id = darshan_record_id_from_path(__path); \
+    rec_ref = darshan_lookup_record_ref(posix_runtime->rec_id_hash, &rec_id, sizeof(darshan_record_id)); \
+    if(!rec_ref) { \
+        rec_ref = posix_track_new_file_record(rec_id, __path); \
+    } \
+    if(rec_ref) { \
+        POSIX_RECORD_STAT(rec_ref, __statbuf, __tm1, __tm2); \
</span>     } \
 } while(0)
 
<span style="background: #ffdddd; color: #000000">-#define POSIX_RECORD_STAT(__file, __statbuf, __tm1, __tm2) do { \
-    (__file)->file_record->counters[POSIX_STATS] += 1; \
-    DARSHAN_TIMER_INC_NO_OVERLAP((__file)->file_record->fcounters[POSIX_F_META_TIME], \
-        __tm1, __tm2, (__file)->last_meta_end); \
</span><span style="background: #ddffdd; color: #000000">+#define POSIX_RECORD_STAT(__rec_ref, __statbuf, __tm1, __tm2) do { \
+    (__rec_ref)->file_rec->counters[POSIX_STATS] += 1; \
+    DARSHAN_TIMER_INC_NO_OVERLAP((__rec_ref)->file_rec->fcounters[POSIX_F_META_TIME], \
+        __tm1, __tm2, (__rec_ref)->last_meta_end); \
</span> } while(0)
 
 
<span style="color: #aaaaaa">@@ -776,6 +737,7 @@ size_t DARSHAN_DECL(fread)(void *ptr, size_t size, size_t nmemb, FILE *stream)
</span> {
     size_t ret;
     int aligned_flag = 0;
<span style="background: #ddffdd; color: #000000">+    int fd;
</span>     double tm1, tm2;
 
     MAP_OR_FAIL(fread);
<span style="color: #aaaaaa">@@ -788,15 +750,14 @@ size_t DARSHAN_DECL(fread)(void *ptr, size_t size, size_t nmemb, FILE *stream)
</span> 
     POSIX_LOCK();
     posix_runtime_initialize();
<span style="background: #ddffdd; color: #000000">+    fd = fileno(stream);
</span>     if(ret > 0)
     {
<span style="background: #ffdddd; color: #000000">-        POSIX_RECORD_READ(size*ret, fileno(stream), 0, 0,
-            aligned_flag, 1, tm1, tm2);
</span><span style="background: #ddffdd; color: #000000">+        POSIX_RECORD_READ(size*ret, fd, 0, 0, aligned_flag, 1, tm1, tm2);
</span>     }
     else
     {
<span style="background: #ffdddd; color: #000000">-        POSIX_RECORD_READ(ret, fileno(stream), 0, 0,
-            aligned_flag, 1, tm1, tm2);
</span><span style="background: #ddffdd; color: #000000">+        POSIX_RECORD_READ(ret, fd, 0, 0, aligned_flag, 1, tm1, tm2);
</span>     }
     POSIX_UNLOCK();
 
<span style="color: #aaaaaa">@@ -807,6 +768,7 @@ size_t DARSHAN_DECL(fwrite)(const void *ptr, size_t size, size_t nmemb, FILE *st
</span> {
     size_t ret;
     int aligned_flag = 0;
<span style="background: #ddffdd; color: #000000">+    int fd;
</span>     double tm1, tm2;
 
     MAP_OR_FAIL(fwrite);
<span style="color: #aaaaaa">@@ -819,15 +781,14 @@ size_t DARSHAN_DECL(fwrite)(const void *ptr, size_t size, size_t nmemb, FILE *st
</span> 
     POSIX_LOCK();
     posix_runtime_initialize();
<span style="background: #ddffdd; color: #000000">+    fd = fileno(stream);
</span>     if(ret > 0)
     {
<span style="background: #ffdddd; color: #000000">-        POSIX_RECORD_WRITE(size*ret, fileno(stream), 0, 0,
-            aligned_flag, 1, tm1, tm2);
</span><span style="background: #ddffdd; color: #000000">+        POSIX_RECORD_WRITE(size*ret, fd, 0, 0, aligned_flag, 1, tm1, tm2);
</span>     }
     else
     {
<span style="background: #ffdddd; color: #000000">-        POSIX_RECORD_WRITE(ret, fileno(stream), 0, 0,
-            aligned_flag, 1, tm1, tm2);
</span><span style="background: #ddffdd; color: #000000">+        POSIX_RECORD_WRITE(ret, fd, 0, 0, aligned_flag, 1, tm1, tm2);
</span>     }
     POSIX_UNLOCK();
 
<span style="color: #aaaaaa">@@ -837,7 +798,7 @@ size_t DARSHAN_DECL(fwrite)(const void *ptr, size_t size, size_t nmemb, FILE *st
</span> off_t DARSHAN_DECL(lseek)(int fd, off_t offset, int whence)
 {
     off_t ret;
<span style="background: #ffdddd; color: #000000">-    struct posix_file_runtime* file;
</span><span style="background: #ddffdd; color: #000000">+    struct posix_file_record_ref *rec_ref;
</span>     double tm1, tm2;
 
     MAP_OR_FAIL(lseek);
<span style="color: #aaaaaa">@@ -850,14 +811,15 @@ off_t DARSHAN_DECL(lseek)(int fd, off_t offset, int whence)
</span>     {
         POSIX_LOCK();
         posix_runtime_initialize();
<span style="background: #ffdddd; color: #000000">-        file = posix_file_by_fd(fd);
-        if(file)
</span><span style="background: #ddffdd; color: #000000">+        if(!posix_runtime || instrumentation_disabled) return(ret); /* XXX: PREMABLE??? */\
+        rec_ref = darshan_lookup_record_ref(posix_runtime->fd_hash, &fd, sizeof(int));
+        if(rec_ref)
</span>         {
<span style="background: #ffdddd; color: #000000">-            file->offset = ret;
</span><span style="background: #ddffdd; color: #000000">+            rec_ref->offset = ret;
</span>             DARSHAN_TIMER_INC_NO_OVERLAP(
<span style="background: #ffdddd; color: #000000">-                file->file_record->fcounters[POSIX_F_META_TIME],
-                tm1, tm2, file->last_meta_end);
-            file->file_record->counters[POSIX_SEEKS] += 1;
</span><span style="background: #ddffdd; color: #000000">+                rec_ref->file_rec->fcounters[POSIX_F_META_TIME],
+                tm1, tm2, rec_ref->last_meta_end);
+            rec_ref->file_rec->counters[POSIX_SEEKS] += 1;
</span>         }
         POSIX_UNLOCK();
     }
<span style="color: #aaaaaa">@@ -868,7 +830,7 @@ off_t DARSHAN_DECL(lseek)(int fd, off_t offset, int whence)
</span> off_t DARSHAN_DECL(lseek64)(int fd, off_t offset, int whence)
 {
     off_t ret;
<span style="background: #ffdddd; color: #000000">-    struct posix_file_runtime* file;
</span><span style="background: #ddffdd; color: #000000">+    struct posix_file_record_ref *rec_ref;
</span>     double tm1, tm2;
 
     MAP_OR_FAIL(lseek64);
<span style="color: #aaaaaa">@@ -881,14 +843,15 @@ off_t DARSHAN_DECL(lseek64)(int fd, off_t offset, int whence)
</span>     {
         POSIX_LOCK();
         posix_runtime_initialize();
<span style="background: #ffdddd; color: #000000">-        file = posix_file_by_fd(fd);
-        if(file)
</span><span style="background: #ddffdd; color: #000000">+        if(!posix_runtime || instrumentation_disabled) return(ret); /* XXX: PREMABLE??? */
+        rec_ref = darshan_lookup_record_ref(posix_runtime->fd_hash, &fd, sizeof(int));
+        if(rec_ref)
</span>         {
<span style="background: #ffdddd; color: #000000">-            file->offset = ret;
</span><span style="background: #ddffdd; color: #000000">+            rec_ref->offset = ret;
</span>             DARSHAN_TIMER_INC_NO_OVERLAP(
<span style="background: #ffdddd; color: #000000">-                file->file_record->fcounters[POSIX_F_META_TIME],
-                tm1, tm2, file->last_meta_end);
-            file->file_record->counters[POSIX_SEEKS] += 1;
</span><span style="background: #ddffdd; color: #000000">+                rec_ref->file_rec->fcounters[POSIX_F_META_TIME],
+                tm1, tm2, rec_ref->last_meta_end);
+            rec_ref->file_rec->counters[POSIX_SEEKS] += 1;
</span>         }
         POSIX_UNLOCK();
     }
<span style="color: #aaaaaa">@@ -899,7 +862,8 @@ off_t DARSHAN_DECL(lseek64)(int fd, off_t offset, int whence)
</span> int DARSHAN_DECL(fseek)(FILE *stream, long offset, int whence)
 {
     int ret;
<span style="background: #ffdddd; color: #000000">-    struct posix_file_runtime* file;
</span><span style="background: #ddffdd; color: #000000">+    struct posix_file_record_ref *rec_ref;
+    int fd;
</span>     double tm1, tm2;
 
     MAP_OR_FAIL(fseek);
<span style="color: #aaaaaa">@@ -912,14 +876,16 @@ int DARSHAN_DECL(fseek)(FILE *stream, long offset, int whence)
</span>     {
         POSIX_LOCK();
         posix_runtime_initialize();
<span style="background: #ffdddd; color: #000000">-        file = posix_file_by_fd(fileno(stream));
-        if(file)
</span><span style="background: #ddffdd; color: #000000">+        if(!posix_runtime || instrumentation_disabled) return(ret); /* XXX: PREMABLE??? */
+        fd = fileno(stream);
+        rec_ref = darshan_lookup_record_ref(posix_runtime->fd_hash, &fd, sizeof(int));
+        if(rec_ref)
</span>         {
<span style="background: #ffdddd; color: #000000">-            file->offset = ftell(stream);
</span><span style="background: #ddffdd; color: #000000">+            rec_ref->offset = ftell(stream);
</span>             DARSHAN_TIMER_INC_NO_OVERLAP(
<span style="background: #ffdddd; color: #000000">-                file->file_record->fcounters[POSIX_F_META_TIME],
-                tm1, tm2, file->last_meta_end);
-            file->file_record->counters[POSIX_FSEEKS] += 1;
</span><span style="background: #ddffdd; color: #000000">+                rec_ref->file_rec->fcounters[POSIX_F_META_TIME],
+                tm1, tm2, rec_ref->last_meta_end);
+            rec_ref->file_rec->counters[POSIX_FSEEKS] += 1;
</span>         }
         POSIX_UNLOCK();
     }
<span style="color: #aaaaaa">@@ -1018,7 +984,7 @@ int DARSHAN_DECL(__lxstat64)(int vers, const char *path, struct stat64 *buf)
</span> int DARSHAN_DECL(__fxstat)(int vers, int fd, struct stat *buf)
 {
     int ret;
<span style="background: #ffdddd; color: #000000">-    struct posix_file_runtime* file;
</span><span style="background: #ddffdd; color: #000000">+    struct posix_file_record_ref *rec_ref;
</span>     double tm1, tm2;
 
     MAP_OR_FAIL(__fxstat);
<span style="color: #aaaaaa">@@ -1032,10 +998,11 @@ int DARSHAN_DECL(__fxstat)(int vers, int fd, struct stat *buf)
</span> 
     POSIX_LOCK();
     posix_runtime_initialize();
<span style="background: #ffdddd; color: #000000">-    file = posix_file_by_fd(fd);
-    if(file)
</span><span style="background: #ddffdd; color: #000000">+    if(!posix_runtime || instrumentation_disabled) return(ret); /* XXX: PREMABLE??? */
+    rec_ref = darshan_lookup_record_ref(posix_runtime->fd_hash, &fd, sizeof(int));
+    if(rec_ref)
</span>     {
<span style="background: #ffdddd; color: #000000">-        POSIX_RECORD_STAT(file, buf, tm1, tm2);
</span><span style="background: #ddffdd; color: #000000">+        POSIX_RECORD_STAT(rec_ref, buf, tm1, tm2);
</span>     }
     POSIX_UNLOCK();
 
<span style="color: #aaaaaa">@@ -1045,7 +1012,7 @@ int DARSHAN_DECL(__fxstat)(int vers, int fd, struct stat *buf)
</span> int DARSHAN_DECL(__fxstat64)(int vers, int fd, struct stat64 *buf)
 {
     int ret;
<span style="background: #ffdddd; color: #000000">-    struct posix_file_runtime* file;
</span><span style="background: #ddffdd; color: #000000">+    struct posix_file_record_ref *rec_ref;
</span>     double tm1, tm2;
 
     MAP_OR_FAIL(__fxstat64);
<span style="color: #aaaaaa">@@ -1059,10 +1026,11 @@ int DARSHAN_DECL(__fxstat64)(int vers, int fd, struct stat64 *buf)
</span> 
     POSIX_LOCK();
     posix_runtime_initialize();
<span style="background: #ffdddd; color: #000000">-    file = posix_file_by_fd(fd);
-    if(file)
</span><span style="background: #ddffdd; color: #000000">+    if(!posix_runtime || instrumentation_disabled) return(ret); /* XXX: PREMABLE??? */
+    rec_ref = darshan_lookup_record_ref(posix_runtime->fd_hash, &fd, sizeof(int));
+    if(rec_ref)
</span>     {
<span style="background: #ffdddd; color: #000000">-        POSIX_RECORD_STAT(file, buf, tm1, tm2);
</span><span style="background: #ddffdd; color: #000000">+        POSIX_RECORD_STAT(rec_ref, buf, tm1, tm2);
</span>     }
     POSIX_UNLOCK();
 
<span style="color: #aaaaaa">@@ -1073,7 +1041,7 @@ void* DARSHAN_DECL(mmap)(void *addr, size_t length, int prot, int flags,
</span>     int fd, off_t offset)
 {
     void* ret;
<span style="background: #ffdddd; color: #000000">-    struct posix_file_runtime* file;
</span><span style="background: #ddffdd; color: #000000">+    struct posix_file_record_ref *rec_ref;
</span> 
     MAP_OR_FAIL(mmap);
 
<span style="color: #aaaaaa">@@ -1083,10 +1051,11 @@ void* DARSHAN_DECL(mmap)(void *addr, size_t length, int prot, int flags,
</span> 
     POSIX_LOCK();
     posix_runtime_initialize();
<span style="background: #ffdddd; color: #000000">-    file = posix_file_by_fd(fd);
-    if(file)
</span><span style="background: #ddffdd; color: #000000">+    if(!posix_runtime || instrumentation_disabled) return(ret); /* XXX: PREMABLE??? */
+    rec_ref = darshan_lookup_record_ref(posix_runtime->fd_hash, &fd, sizeof(int));
+    if(rec_ref)
</span>     {
<span style="background: #ffdddd; color: #000000">-        file->file_record->counters[POSIX_MMAPS] += 1;
</span><span style="background: #ddffdd; color: #000000">+        rec_ref->file_rec->counters[POSIX_MMAPS] += 1;
</span>     }
     POSIX_UNLOCK();
 
<span style="color: #aaaaaa">@@ -1097,7 +1066,7 @@ void* DARSHAN_DECL(mmap64)(void *addr, size_t length, int prot, int flags,
</span>     int fd, off64_t offset)
 {
     void* ret;
<span style="background: #ffdddd; color: #000000">-    struct posix_file_runtime* file;
</span><span style="background: #ddffdd; color: #000000">+    struct posix_file_record_ref *rec_ref;
</span> 
     MAP_OR_FAIL(mmap64);
 
<span style="color: #aaaaaa">@@ -1107,10 +1076,11 @@ void* DARSHAN_DECL(mmap64)(void *addr, size_t length, int prot, int flags,
</span> 
     POSIX_LOCK();
     posix_runtime_initialize();
<span style="background: #ffdddd; color: #000000">-    file = posix_file_by_fd(fd);
-    if(file)
</span><span style="background: #ddffdd; color: #000000">+    if(!posix_runtime || instrumentation_disabled) return(ret); /* XXX: PREMABLE??? */
+    rec_ref = darshan_lookup_record_ref(posix_runtime->fd_hash, &fd, sizeof(int));
+    if(rec_ref)
</span>     {
<span style="background: #ffdddd; color: #000000">-        file->file_record->counters[POSIX_MMAPS] += 1;
</span><span style="background: #ddffdd; color: #000000">+        rec_ref->file_rec->counters[POSIX_MMAPS] += 1;
</span>     }
     POSIX_UNLOCK();
 
<span style="color: #aaaaaa">@@ -1120,7 +1090,7 @@ void* DARSHAN_DECL(mmap64)(void *addr, size_t length, int prot, int flags,
</span> int DARSHAN_DECL(fsync)(int fd)
 {
     int ret;
<span style="background: #ffdddd; color: #000000">-    struct posix_file_runtime* file;
</span><span style="background: #ddffdd; color: #000000">+    struct posix_file_record_ref *rec_ref;
</span>     double tm1, tm2;
 
     MAP_OR_FAIL(fsync);
<span style="color: #aaaaaa">@@ -1134,13 +1104,14 @@ int DARSHAN_DECL(fsync)(int fd)
</span> 
     POSIX_LOCK();
     posix_runtime_initialize();
<span style="background: #ffdddd; color: #000000">-    file = posix_file_by_fd(fd);
-    if(file)
</span><span style="background: #ddffdd; color: #000000">+    if(!posix_runtime || instrumentation_disabled) return(ret); /* XXX: PREMABLE??? */
+    rec_ref = darshan_lookup_record_ref(posix_runtime->fd_hash, &fd, sizeof(int));
+    if(rec_ref)
</span>     {
         DARSHAN_TIMER_INC_NO_OVERLAP(
<span style="background: #ffdddd; color: #000000">-            file->file_record->fcounters[POSIX_F_WRITE_TIME],
-            tm1, tm2, file->last_write_end);
-        file->file_record->counters[POSIX_FSYNCS] += 1;
</span><span style="background: #ddffdd; color: #000000">+            rec_ref->file_rec->fcounters[POSIX_F_WRITE_TIME],
+            tm1, tm2, rec_ref->last_write_end);
+        rec_ref->file_rec->counters[POSIX_FSYNCS] += 1;
</span>     }
     POSIX_UNLOCK();
 
<span style="color: #aaaaaa">@@ -1150,7 +1121,7 @@ int DARSHAN_DECL(fsync)(int fd)
</span> int DARSHAN_DECL(fdatasync)(int fd)
 {
     int ret;
<span style="background: #ffdddd; color: #000000">-    struct posix_file_runtime* file;
</span><span style="background: #ddffdd; color: #000000">+    struct posix_file_record_ref *rec_ref;
</span>     double tm1, tm2;
 
     MAP_OR_FAIL(fdatasync);
<span style="color: #aaaaaa">@@ -1164,13 +1135,14 @@ int DARSHAN_DECL(fdatasync)(int fd)
</span> 
     POSIX_LOCK();
     posix_runtime_initialize();
<span style="background: #ffdddd; color: #000000">-    file = posix_file_by_fd(fd);
-    if(file)
</span><span style="background: #ddffdd; color: #000000">+    if(!posix_runtime || instrumentation_disabled) return(ret); /* XXX: PREMABLE??? */
+    rec_ref = darshan_lookup_record_ref(posix_runtime->fd_hash, &fd, sizeof(int));
+    if(rec_ref)
</span>     {
         DARSHAN_TIMER_INC_NO_OVERLAP(
<span style="background: #ffdddd; color: #000000">-            file->file_record->fcounters[POSIX_F_WRITE_TIME],
-            tm1, tm2, file->last_write_end);
-        file->file_record->counters[POSIX_FDSYNCS] += 1;
</span><span style="background: #ddffdd; color: #000000">+            rec_ref->file_rec->fcounters[POSIX_F_WRITE_TIME],
+            tm1, tm2, rec_ref->last_write_end);
+        rec_ref->file_rec->counters[POSIX_FDSYNCS] += 1;
</span>     }
     POSIX_UNLOCK();
 
<span style="color: #aaaaaa">@@ -1179,9 +1151,9 @@ int DARSHAN_DECL(fdatasync)(int fd)
</span> 
 int DARSHAN_DECL(close)(int fd)
 {
<span style="background: #ffdddd; color: #000000">-    struct posix_file_runtime* file;
-    double tm1, tm2;
</span>     int ret;
<span style="background: #ddffdd; color: #000000">+    struct posix_file_record_ref *rec_ref;
+    double tm1, tm2;
</span> 
     MAP_OR_FAIL(close);
 
<span style="color: #aaaaaa">@@ -1191,17 +1163,18 @@ int DARSHAN_DECL(close)(int fd)
</span> 
     POSIX_LOCK();
     posix_runtime_initialize();
<span style="background: #ffdddd; color: #000000">-    file = posix_file_by_fd(fd);
-    if(file)
</span><span style="background: #ddffdd; color: #000000">+    if(!posix_runtime || instrumentation_disabled) return(ret); /* XXX: PREMABLE??? */
+    rec_ref = darshan_lookup_record_ref(posix_runtime->fd_hash, &fd, sizeof(int));
+    if(rec_ref)
</span>     {
<span style="background: #ffdddd; color: #000000">-        file->last_byte_written = 0;
-        file->last_byte_read = 0;
-        file->file_record->fcounters[POSIX_F_CLOSE_TIMESTAMP] =
</span><span style="background: #ddffdd; color: #000000">+        rec_ref->last_byte_written = 0;
+        rec_ref->last_byte_read = 0;
+        rec_ref->file_rec->fcounters[POSIX_F_CLOSE_TIMESTAMP] =
</span>             darshan_core_wtime();
         DARSHAN_TIMER_INC_NO_OVERLAP(
<span style="background: #ffdddd; color: #000000">-            file->file_record->fcounters[POSIX_F_META_TIME],
-            tm1, tm2, file->last_meta_end);
-        posix_file_close_fd(fd);
</span><span style="background: #ddffdd; color: #000000">+            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));
</span>     }
     POSIX_UNLOCK();    
 
<span style="color: #aaaaaa">@@ -1210,10 +1183,10 @@ int DARSHAN_DECL(close)(int fd)
</span> 
 int DARSHAN_DECL(fclose)(FILE *fp)
 {
<span style="background: #ffdddd; color: #000000">-    struct posix_file_runtime* file;
</span><span style="background: #ddffdd; color: #000000">+    int ret;
+    struct posix_file_record_ref *rec_ref;
</span>     int fd = fileno(fp);
     double tm1, tm2;
<span style="background: #ffdddd; color: #000000">-    int ret;
</span> 
     MAP_OR_FAIL(fclose);
 
<span style="color: #aaaaaa">@@ -1223,17 +1196,18 @@ int DARSHAN_DECL(fclose)(FILE *fp)
</span> 
     POSIX_LOCK();
     posix_runtime_initialize();
<span style="background: #ffdddd; color: #000000">-    file = posix_file_by_fd(fd);
-    if(file)
</span><span style="background: #ddffdd; color: #000000">+    if(!posix_runtime || instrumentation_disabled) return(ret); /* XXX: PREMABLE??? */
+    rec_ref = darshan_lookup_record_ref(posix_runtime->fd_hash, &fd, sizeof(int));
+    if(rec_ref)
</span>     {
<span style="background: #ffdddd; color: #000000">-        file->last_byte_written = 0;
-        file->last_byte_read = 0;
-        file->file_record->fcounters[POSIX_F_CLOSE_TIMESTAMP] =
</span><span style="background: #ddffdd; color: #000000">+        rec_ref->last_byte_written = 0;
+        rec_ref->last_byte_read = 0;
+        rec_ref->file_rec->fcounters[POSIX_F_CLOSE_TIMESTAMP] =
</span>             darshan_core_wtime();
         DARSHAN_TIMER_INC_NO_OVERLAP(
<span style="background: #ffdddd; color: #000000">-            file->file_record->fcounters[POSIX_F_META_TIME],
-            tm1, tm2, file->last_meta_end);
-        posix_file_close_fd(fd);
</span><span style="background: #ddffdd; color: #000000">+            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));
</span>     }
     POSIX_UNLOCK();
 
<span style="color: #aaaaaa">@@ -1327,7 +1301,7 @@ ssize_t DARSHAN_DECL(aio_return)(struct aiocb *aiocbp)
</span>     POSIX_LOCK();
     posix_runtime_initialize();
     tmp = posix_aio_tracker_del(aiocbp->aio_fildes, aiocbp);
<span style="background: #ffdddd; color: #000000">-    if (tmp)
</span><span style="background: #ddffdd; color: #000000">+    if(tmp)
</span>     {
         if((unsigned long)aiocbp->aio_buf % darshan_mem_alignment == 0)
             aligned_flag = 1;
<span style="color: #aaaaaa">@@ -1365,7 +1339,7 @@ ssize_t DARSHAN_DECL(aio_return64)(struct aiocb64 *aiocbp)
</span>     POSIX_LOCK();
     posix_runtime_initialize();
     tmp = posix_aio_tracker_del(aiocbp->aio_fildes, aiocbp);
<span style="background: #ffdddd; color: #000000">-    if (tmp)
</span><span style="background: #ddffdd; color: #000000">+    if(tmp)
</span>     {
         if((unsigned long)aiocbp->aio_buf % darshan_mem_alignment == 0)
             aligned_flag = 1;
<span style="color: #aaaaaa">@@ -1482,138 +1456,60 @@ static void posix_runtime_initialize()
</span>     return;
 }
 
<span style="background: #ffdddd; color: #000000">-/* get a POSIX file record for the given file path */
-static struct posix_file_runtime* posix_file_by_name(const char *name)
</span><span style="background: #ddffdd; color: #000000">+static struct posix_file_record_ref *posix_track_new_file_record(
+    darshan_record_id rec_id, const char *path)
</span> {
<span style="background: #ffdddd; color: #000000">-    struct posix_file_runtime *file_rec_rt;
</span>     struct darshan_posix_file *file_rec = NULL;
<span style="background: #ffdddd; color: #000000">-    char *newname = NULL;
-    darshan_record_id file_id;
</span><span style="background: #ddffdd; color: #000000">+    struct posix_file_record_ref *rec_ref = NULL;
+    char *newpath = NULL;
</span>     int file_alignment;
<span style="background: #ddffdd; color: #000000">+    int ret;
</span> 
<span style="background: #ffdddd; color: #000000">-    if(!posix_runtime || instrumentation_disabled)
</span><span style="background: #ddffdd; color: #000000">+    rec_ref = malloc(sizeof(*rec_ref));
+    if(!rec_ref)
</span>         return(NULL);
<span style="background: #ddffdd; color: #000000">+    memset(rec_ref, 0, sizeof(*rec_ref));
</span> 
<span style="background: #ffdddd; color: #000000">-    newname = darshan_clean_file_path(name);
-    if(!newname)
-        newname = (char*)name;
-
-    /* lookup the id for this filename */
-    file_id = darshan_core_gen_record_id(newname);
-
-    /* search the hash table for this file record, and return if found */
-    HASH_FIND(hlink, posix_runtime->file_hash, &file_id,
-        sizeof(darshan_record_id), file_rec_rt);
-    if(file_rec_rt == NULL)
</span><span style="background: #ddffdd; color: #000000">+    /* add a reference to this file record based on record id */
+    ret = darshan_add_record_ref(&(posix_runtime->rec_id_hash), &rec_id,
+        sizeof(darshan_record_id), rec_ref);
+    if(ret == 0)
</span>     {
<span style="background: #ffdddd; color: #000000">-        file_rec_rt = malloc(sizeof(*file_rec_rt));
-        if(file_rec_rt)
-        {
-            memset(file_rec_rt, 0, sizeof(*file_rec_rt));
-
-            /* attempt to register the record with darshan core */
-            file_rec = darshan_core_register_record(file_id, newname, DARSHAN_POSIX_MOD,
-                sizeof(struct darshan_posix_file), &file_alignment);
-            if(!file_rec)
-                free(file_rec_rt);
-        }
-
-        if(file_rec != NULL)
-        {
-            /* register was successful, init structures */
-            file_rec->base_rec.id = file_id;
-            file_rec->base_rec.rank = my_rank;
-            file_rec->counters[POSIX_MEM_ALIGNMENT] = darshan_mem_alignment;
-            file_rec->counters[POSIX_FILE_ALIGNMENT] = file_alignment;
-            file_rec_rt->file_record = file_rec;
-
-            /* add new record to file hash table */
-            HASH_ADD(hlink, posix_runtime->file_hash, file_record->base_rec.id,
-                sizeof(darshan_record_id), file_rec_rt);
-        }
-    }
-
-    if(newname != name)
-        free(newname);
-    return(file_rec_rt);
-}
-
-/* get a POSIX file record for the given file path, and also create a
- * reference structure using the returned file descriptor
- */
-static struct posix_file_runtime* posix_file_by_name_setfd(const char* name, int fd)
-{
-    struct posix_file_runtime* file;
-    struct posix_file_runtime_ref* ref;
-
-    if(!posix_runtime || instrumentation_disabled)
-        return(NULL);
-
-    /* find file record by name first */
-    file = posix_file_by_name(name);
-    if(!file)
</span><span style="background: #ddffdd; color: #000000">+        free(rec_ref);
</span>         return(NULL);
<span style="background: #ffdddd; color: #000000">-
-    /* search hash table for existing file ref for this fd */
-    HASH_FIND(hlink, posix_runtime->fd_hash, &fd, sizeof(int), ref);
-    if(ref)
-    {
-        /* we have a reference.  Make sure it points to the correct file
-         * and return it
-         */
-        ref->file = file;
-        return(file);
</span>     }
 
<span style="background: #ffdddd; color: #000000">-    /* if we hit this point, then we don't have a reference for this fd
-     * in the table yet.  Add it.
-     */
-    ref = malloc(sizeof(*ref));
-    if(!ref)
-        return(NULL);
-    memset(ref, 0, sizeof(*ref));
-
-    ref->file = file;
-    ref->fd = fd;    
-    HASH_ADD(hlink, posix_runtime->fd_hash, fd, sizeof(int), ref);
-
-    return(file);
-}
-
-/* get a POSIX file record for the given file descriptor */
-static struct posix_file_runtime* posix_file_by_fd(int fd)
-{
-    struct posix_file_runtime_ref* ref;
-
-    if(!posix_runtime || instrumentation_disabled)
-        return(NULL);
-
-    /* search hash table for existing file ref for this fd */
-    HASH_FIND(hlink, posix_runtime->fd_hash, &fd, sizeof(int), ref);
-    if(ref)
-        return(ref->file);
</span><span style="background: #ddffdd; color: #000000">+    /* cleanup name and convert to absolute path */
+    newpath = darshan_clean_file_path(path);
+    if(!newpath)
+        newpath = (char *)path;
</span> 
<span style="background: #ffdddd; color: #000000">-    return(NULL);
-}
-
-/* free up reference data structures for the given file descriptor */
-static void posix_file_close_fd(int fd)
-{
-    struct posix_file_runtime_ref* ref;
-
-    if(!posix_runtime || instrumentation_disabled)
-        return;
-
-    /* search hash table for this fd */
-    HASH_FIND(hlink, posix_runtime->fd_hash, &fd, sizeof(int), ref);
-    if(ref)
</span><span style="background: #ddffdd; color: #000000">+    /* register the actual file record with darshan-core so it is persisted
+     * in the log file
+     */
+    file_rec = darshan_core_register_record(rec_id, newpath, DARSHAN_POSIX_MOD,
+        sizeof(struct darshan_posix_file), &file_alignment);
+    if(!file_rec)
</span>     {
<span style="background: #ffdddd; color: #000000">-        /* we have a reference, delete it */
-        HASH_DELETE(hlink, posix_runtime->fd_hash, ref);
-        free(ref);
</span><span style="background: #ddffdd; color: #000000">+        darshan_delete_record_ref(&(posix_runtime->rec_id_hash),
+            &rec_id, sizeof(darshan_record_id));
+        free(rec_ref);
+        if(newpath != path)
+            free(newpath);
+        return(NULL);
</span>     }
 
<span style="background: #ffdddd; color: #000000">-    return;
</span><span style="background: #ddffdd; color: #000000">+    /* registering this file record was successful, so initialize some fields */
+    file_rec->base_rec.id = rec_id;
+    file_rec->base_rec.rank = my_rank;
+    file_rec->counters[POSIX_MEM_ALIGNMENT] = darshan_mem_alignment;
+    file_rec->counters[POSIX_FILE_ALIGNMENT] = file_alignment;
+    rec_ref->file_rec = file_rec;
+    posix_runtime->file_rec_count++;
+
+    if(newpath != path)
+        free(newpath);
+    return(rec_ref);
</span> }
 
 /* compare function for sorting file records by descending rank */
<span style="color: #aaaaaa">@@ -1638,16 +1534,16 @@ static int posix_record_compare(const void* a_p, const void* b_p)
</span> static struct posix_aio_tracker* posix_aio_tracker_del(int fd, void *aiocbp)
 {
     struct posix_aio_tracker *tracker = NULL, *iter, *tmp;
<span style="background: #ffdddd; color: #000000">-    struct posix_file_runtime* file;
</span><span style="background: #ddffdd; color: #000000">+    struct posix_file_record_ref *rec_ref;
</span> 
<span style="background: #ffdddd; color: #000000">-    file = posix_file_by_fd(fd);
-    if (file)
</span><span style="background: #ddffdd; color: #000000">+    rec_ref = darshan_lookup_record_ref(posix_runtime->fd_hash, &fd, sizeof(int));
+    if(rec_ref)
</span>     {
<span style="background: #ffdddd; color: #000000">-        LL_FOREACH_SAFE(file->aio_list, iter, tmp)
</span><span style="background: #ddffdd; color: #000000">+        LL_FOREACH_SAFE(rec_ref->aio_list, iter, tmp)
</span>         {
<span style="background: #ffdddd; color: #000000">-            if (iter->aiocbp == aiocbp)
</span><span style="background: #ddffdd; color: #000000">+            if(iter->aiocbp == aiocbp)
</span>             {
<span style="background: #ffdddd; color: #000000">-                LL_DELETE(file->aio_list, iter);
</span><span style="background: #ddffdd; color: #000000">+                LL_DELETE(rec_ref->aio_list, iter);
</span>                 tracker = iter;
                 break;
             }
<span style="color: #aaaaaa">@@ -1661,17 +1557,17 @@ static struct posix_aio_tracker* posix_aio_tracker_del(int fd, void *aiocbp)
</span> static void posix_aio_tracker_add(int fd, void *aiocbp)
 {
     struct posix_aio_tracker* tracker;
<span style="background: #ffdddd; color: #000000">-    struct posix_file_runtime* file;
</span><span style="background: #ddffdd; color: #000000">+    struct posix_file_record_ref *rec_ref;
</span> 
<span style="background: #ffdddd; color: #000000">-    file = posix_file_by_fd(fd);
-    if (file)
</span><span style="background: #ddffdd; color: #000000">+    rec_ref = darshan_lookup_record_ref(posix_runtime->fd_hash, &fd, sizeof(int));
+    if(rec_ref)
</span>     {
         tracker = malloc(sizeof(*tracker));
<span style="background: #ffdddd; color: #000000">-        if (tracker)
</span><span style="background: #ddffdd; color: #000000">+        if(tracker)
</span>         {
             tracker->tm1 = darshan_core_wtime();
             tracker->aiocbp = aiocbp;
<span style="background: #ffdddd; color: #000000">-            LL_PREPEND(file->aio_list, tracker);
</span><span style="background: #ddffdd; color: #000000">+            LL_PREPEND(rec_ref->aio_list, tracker);
</span>         }
     }
 
<span style="color: #aaaaaa">@@ -2005,6 +1901,32 @@ static void posix_begin_shutdown()
</span>     return;
 }
 
<span style="background: #ddffdd; color: #000000">+static void posix_finalize_file_records(void *rec_ref_p)
+{
+    struct posix_file_record_ref *rec_ref =
+        (struct posix_file_record_ref *)rec_ref_p;
+
+#ifndef __DARSHAN_ENABLE_MMAP_LOGS
+    /* walk common counters to get 4 most common -- only if mmap
+     * feature is disabled (mmap updates counters on the go)
+     */
+
+    /* common accesses */
+    darshan_walk_common_vals(rec_ref->access_root,
+        &(rec_ref->file_rec->counters[POSIX_ACCESS1_ACCESS]),
+        &(rec_ref->file_rec->counters[POSIX_ACCESS1_COUNT]));
+    /* common strides */
+    darshan_walk_common_vals(rec_ref->stride_root,
+        &(rec_ref->file_rec->counters[POSIX_STRIDE1_STRIDE]),
+        &(rec_ref->file_rec->counters[POSIX_STRIDE1_COUNT]));
+#endif
+
+    tdestroy(rec_ref->access_root, free);
+    tdestroy(rec_ref->stride_root, free);
+
+    return;
+}
+
</span> static void posix_get_output_data(
     MPI_Comm mod_comm,
     darshan_record_id *shared_recs,
<span style="color: #aaaaaa">@@ -2012,10 +1934,10 @@ static void posix_get_output_data(
</span>     void **posix_buf,
     int *posix_buf_sz)
 {
<span style="background: #ffdddd; color: #000000">-    struct posix_file_runtime *file_rec_rt, *tmp;
</span><span style="background: #ddffdd; color: #000000">+    struct posix_file_record_ref *rec_ref;
</span>     struct darshan_posix_file *posix_rec_buf = *(struct darshan_posix_file **)posix_buf;
<span style="background: #ffdddd; color: #000000">-    double posix_time;
</span>     int posix_rec_count;
<span style="background: #ddffdd; color: #000000">+    double posix_time;
</span>     struct darshan_posix_file *red_send_buf = NULL;
     struct darshan_posix_file *red_recv_buf = NULL;
     MPI_Datatype red_type;
<span style="color: #aaaaaa">@@ -2023,31 +1945,12 @@ static void posix_get_output_data(
</span>     int i;
 
     assert(posix_runtime);
<span style="background: #ffdddd; color: #000000">-    posix_rec_count = HASH_CNT(hlink, posix_runtime->file_hash);
</span><span style="background: #ddffdd; color: #000000">+    posix_rec_count = posix_runtime->file_rec_count;
</span> 
<span style="background: #ffdddd; color: #000000">-    /* go through file access data for each record and set the 4 most common
-     * stride/access size counters.
</span><span style="background: #ddffdd; color: #000000">+    /* perform any final transformations on POSIX file records before
+     * writing them out to log file
</span>      */
<span style="background: #ffdddd; color: #000000">-    HASH_ITER(hlink, posix_runtime->file_hash, file_rec_rt, tmp)
-    {
-#ifndef __DARSHAN_ENABLE_MMAP_LOGS
-        /* walk common counters to get 4 most common -- only if mmap
-         * feature is disabled (mmap updates counters on the go)
-         */
-
-        /* common accesses */
-        darshan_walk_common_vals(file_rec_rt->access_root,
-            &(file_rec_rt->file_record->counters[POSIX_ACCESS1_ACCESS]),
-            &(file_rec_rt->file_record->counters[POSIX_ACCESS1_COUNT]));
-        /* common strides */
-        darshan_walk_common_vals(file_rec_rt->stride_root,
-            &(file_rec_rt->file_record->counters[POSIX_STRIDE1_STRIDE]),
-            &(file_rec_rt->file_record->counters[POSIX_STRIDE1_COUNT]));
-#endif
-
-        tdestroy(file_rec_rt->access_root, free);
-        tdestroy(file_rec_rt->stride_root, free);
-    }
</span><span style="background: #ddffdd; color: #000000">+    darshan_iter_record_refs(posix_runtime->rec_id_hash, &posix_finalize_file_records);
</span> 
     /* if there are globally shared files, do a shared file reduction */
     /* NOTE: the shared file reduction is also skipped if the 
<span style="color: #aaaaaa">@@ -2058,36 +1961,36 @@ static void posix_get_output_data(
</span>         /* necessary initialization of shared records */
         for(i = 0; i < shared_rec_count; i++)
         {
<span style="background: #ffdddd; color: #000000">-            HASH_FIND(hlink, posix_runtime->file_hash, &shared_recs[i],
-                sizeof(darshan_record_id), file_rec_rt);
-            assert(file_rec_rt);
</span><span style="background: #ddffdd; color: #000000">+            rec_ref = darshan_lookup_record_ref(posix_runtime->rec_id_hash,
+                &shared_recs[i], sizeof(darshan_record_id));
+            assert(rec_ref);
</span> 
             posix_time =
<span style="background: #ffdddd; color: #000000">-                file_rec_rt->file_record->fcounters[POSIX_F_READ_TIME] +
-                file_rec_rt->file_record->fcounters[POSIX_F_WRITE_TIME] +
-                file_rec_rt->file_record->fcounters[POSIX_F_META_TIME];
</span><span style="background: #ddffdd; color: #000000">+                rec_ref->file_rec->fcounters[POSIX_F_READ_TIME] +
+                rec_ref->file_rec->fcounters[POSIX_F_WRITE_TIME] +
+                rec_ref->file_rec->fcounters[POSIX_F_META_TIME];
</span> 
             /* initialize fastest/slowest info prior to the reduction */
<span style="background: #ffdddd; color: #000000">-            file_rec_rt->file_record->counters[POSIX_FASTEST_RANK] =
-                file_rec_rt->file_record->base_rec.rank;
-            file_rec_rt->file_record->counters[POSIX_FASTEST_RANK_BYTES] =
-                file_rec_rt->file_record->counters[POSIX_BYTES_READ] +
-                file_rec_rt->file_record->counters[POSIX_BYTES_WRITTEN];
-            file_rec_rt->file_record->fcounters[POSIX_F_FASTEST_RANK_TIME] =
</span><span style="background: #ddffdd; color: #000000">+            rec_ref->file_rec->counters[POSIX_FASTEST_RANK] =
+                rec_ref->file_rec->base_rec.rank;
+            rec_ref->file_rec->counters[POSIX_FASTEST_RANK_BYTES] =
+                rec_ref->file_rec->counters[POSIX_BYTES_READ] +
+                rec_ref->file_rec->counters[POSIX_BYTES_WRITTEN];
+            rec_ref->file_rec->fcounters[POSIX_F_FASTEST_RANK_TIME] =
</span>                 posix_time;
 
             /* until reduction occurs, we assume that this rank is both
              * the fastest and slowest. It is up to the reduction operator
              * to find the true min and max.
              */
<span style="background: #ffdddd; color: #000000">-            file_rec_rt->file_record->counters[POSIX_SLOWEST_RANK] =
-                file_rec_rt->file_record->counters[POSIX_FASTEST_RANK];
-            file_rec_rt->file_record->counters[POSIX_SLOWEST_RANK_BYTES] =
-                file_rec_rt->file_record->counters[POSIX_FASTEST_RANK_BYTES];
-            file_rec_rt->file_record->fcounters[POSIX_F_SLOWEST_RANK_TIME] =
-                file_rec_rt->file_record->fcounters[POSIX_F_FASTEST_RANK_TIME];
-
-            file_rec_rt->file_record->base_rec.rank = -1;
</span><span style="background: #ddffdd; color: #000000">+            rec_ref->file_rec->counters[POSIX_SLOWEST_RANK] =
+                rec_ref->file_rec->counters[POSIX_FASTEST_RANK];
+            rec_ref->file_rec->counters[POSIX_SLOWEST_RANK_BYTES] =
+                rec_ref->file_rec->counters[POSIX_FASTEST_RANK_BYTES];
+            rec_ref->file_rec->fcounters[POSIX_F_SLOWEST_RANK_TIME] =
+                rec_ref->file_rec->fcounters[POSIX_F_FASTEST_RANK_TIME];
+
+            rec_ref->file_rec->base_rec.rank = -1;
</span>         }
 
         /* sort the array of files descending by rank so that we get all of the 
<span style="color: #aaaaaa">@@ -2151,22 +2054,10 @@ static void posix_get_output_data(
</span> 
 static void posix_shutdown()
 {
<span style="background: #ffdddd; color: #000000">-    struct posix_file_runtime_ref *fd_ref, *fd_tmp;
-    struct posix_file_runtime *file_ref, *file_tmp;
-
</span>     assert(posix_runtime);
 
<span style="background: #ffdddd; color: #000000">-    HASH_ITER(hlink, posix_runtime->fd_hash, fd_ref, fd_tmp)
-    {
-        HASH_DELETE(hlink, posix_runtime->fd_hash, fd_ref);
-        free(fd_ref);
-    }
-
-    HASH_ITER(hlink, posix_runtime->file_hash, file_ref, file_tmp)
-    {
-        HASH_DELETE(hlink, posix_runtime->file_hash, file_ref);
-        free(file_ref);
-    }
</span><span style="background: #ddffdd; color: #000000">+    darshan_clear_record_refs(&(posix_runtime->fd_hash), 0);
+    darshan_clear_record_refs(&(posix_runtime->rec_id_hash), 1);
</span> 
     free(posix_runtime);
     posix_runtime = NULL;
</code></pre>

<br>
</li>

</div>
<div class="footer" style="margin-top: 10px">
<p style="color: #777; font-size: small">

<br>
<a href="https://xgitlab.cels.anl.gov/darshan/darshan/commit/9bfc7b65bb3ed1f77a3dd49e29879d8f95e83e44">View it on GitLab</a>.
<br>
You're receiving this email because of your account on xgitlab.cels.anl.gov.
If you'd like to receive fewer emails, you can
adjust your notification settings.

</p>
</div>
</body>
</html>