[Darshan-commits] [Git][darshan/darshan][master] 6 commits: first cut at dxt trace triggers

Shane Snyder xgitlab at cels.anl.gov
Mon Sep 9 16:03:30 CDT 2019



Shane Snyder pushed to branch master at darshan / darshan


Commits:
9007db12 by Shane Snyder at 2019-08-07T22:09:06Z
first cut at dxt trace triggers

dynamic triggers still not working

- - - - -
d172df2e by Shane Snyder at 2019-08-08T02:31:14Z
add user pointer to record_ref iterators

- - - - -
ea9fb7f2 by Shane Snyder at 2019-08-08T19:38:24Z
code for filtering dynamic trace data

- - - - -
86a9cb00 by Shane Snyder at 2019-08-09T18:51:05Z
finish implementing dynamic trace filtering

- - - - -
d710db8e by Shane Snyder at 2019-08-13T17:54:09Z
add missing dxt header

- - - - -
35a35fe5 by Shane Snyder at 2019-09-09T21:00:41Z
Merge branch 'dev-dynamic-dxt-trigger'

- - - - -


9 changed files:

- darshan-runtime/darshan-common.h
- + darshan-runtime/darshan-dxt.h
- darshan-runtime/lib/darshan-common.c
- darshan-runtime/lib/darshan-core.c
- darshan-runtime/lib/darshan-dxt.c
- darshan-runtime/lib/darshan-lustre.c
- darshan-runtime/lib/darshan-mdhim.c
- darshan-runtime/lib/darshan-mpiio.c
- darshan-runtime/lib/darshan-posix.c


Changes:

=====================================
darshan-runtime/darshan-common.h
=====================================
@@ -210,12 +210,16 @@ void darshan_clear_record_refs(
  *
  * Iterate each record reference stored in the hash table pointed
  * to by 'hash_head' and perform the given action 'iter_action'. 
- * The action function takes a single pointer which points to the
- * corresponding record reference pointer.
+ * The action function takes two pointers as input: the first
+ * points to the corresponding record reference pointer and the
+ * second is a user-supplied pointer provided for the action.
+ * 'user_ptr' is the user-supplied pointer that will be passed
+ * as the 2nd argument to 'iter_action'.
  */
 void darshan_iter_record_refs(
     void *hash_head,
-    void (*iter_action)(void *));
+    void (*iter_action)(void *, void *),
+    void *user_ptr);
 
 /* darshan_clean_file_path()
  *


=====================================
darshan-runtime/darshan-dxt.h
=====================================
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2019 University of Chicago.
+ * See COPYRIGHT notice in top-level directory.
+ *
+ */
+
+#ifndef __DARSHAN_DXT_H
+#define __DARSHAN_DXT_H
+
+/* dxt_load_trigger_conf()
+ *
+ * DXT function exposed to Darshan core to read in any trace triggers
+ * from the file path in 'trigger_conf_path' before module
+ * initialization occurs.
+ */
+void dxt_load_trigger_conf(
+    char *trigger_conf_path);
+
+/* dxt_posix_runtime_initialize()
+ *
+ * DXT function exposed to POSIX module for initializing DXT-POSIX runtime.
+ */
+void dxt_posix_runtime_initialize(void);
+
+/* dxt_mpiio_runtime_initialize()
+ *
+ * DXT function exposed to MPIIO module for initializing DXT-MPIIO runtime.
+ */
+void dxt_mpiio_runtime_initialize(void);
+
+/* dxt_posix_write(), dxt_posix_read()
+ *
+ * DXT function to trace a POSIX write/read call to file record 'rec_id',
+ * at offset 'offset' and with 'length' size. 'start_time' and 'end_time'
+ * are starting and ending timestamps for the operation, respectively.
+ */
+void dxt_posix_write(darshan_record_id rec_id, int64_t offset,
+        int64_t length, double start_time, double end_time);
+void dxt_posix_read(darshan_record_id rec_id, int64_t offset,
+        int64_t length, double start_time, double end_time);
+
+/* dxt_mpiio_write(), dxt_mpiio_read()
+ *
+ * DXT function to trace a MPIIO write/read call to file record 'rec_id',
+ * with 'length' size. 'start_time' and 'end_time' are starting and ending
+ * timestamps for the operation, respectively.
+ */
+void dxt_mpiio_write(darshan_record_id rec_id, int64_t length,
+        double start_time, double end_time);
+void dxt_mpiio_read(darshan_record_id rec_id, int64_t length,
+        double start_time, double end_time);
+
+void dxt_posix_filter_dynamic_traces(
+    struct darshan_posix_file *(*rec_id_to_psx_file)(darshan_record_id));
+
+#endif /* __DARSHAN_DXT_H */


=====================================
darshan-runtime/lib/darshan-common.c
=====================================
@@ -103,7 +103,8 @@ void darshan_clear_record_refs(void **hash_head_p, int free_flag)
     return;
 }
 
-void darshan_iter_record_refs(void *hash_head, void (*iter_action)(void *))
+void darshan_iter_record_refs(void *hash_head, void (*iter_action)(void *, void *),
+    void *user_ptr)
 {
     struct darshan_record_ref_tracker *ref_tracker, *tmp;
     struct darshan_record_ref_tracker *ref_tracker_head =
@@ -114,7 +115,7 @@ void darshan_iter_record_refs(void *hash_head, void (*iter_action)(void *))
      */
     HASH_ITER(hlink, ref_tracker_head, ref_tracker, tmp)
     {
-        iter_action(ref_tracker->rec_ref_p);
+        iter_action(ref_tracker->rec_ref_p, user_ptr);
     }
 
     return;


=====================================
darshan-runtime/lib/darshan-core.c
=====================================
@@ -34,6 +34,7 @@
 #include "darshan.h"
 #include "darshan-core.h"
 #include "darshan-dynamic.h"
+#include "darshan-dxt.h"
 
 #ifdef DARSHAN_LUSTRE
 #include <lustre/lustre_user.h>
@@ -308,6 +309,13 @@ void darshan_core_initialize(int argc, char **argv)
             /* collect information about command line and mounted file systems */
             darshan_get_exe_and_mounts(init_core, argc, argv);
 
+            /* determine if/when DXT should be enabled by looking for triggers */
+            char *trigger_conf = getenv("DARSHAN_DXT_TRIGGER_CONF_PATH");
+            if(trigger_conf)
+            {
+                dxt_load_trigger_conf(trigger_conf);
+            }
+
             /* if darshan was successfully initialized, set the global pointer
              * and bootstrap any modules with static initialization routines
              */


=====================================
darshan-runtime/lib/darshan-dxt.c
=====================================
@@ -24,11 +24,13 @@
 #include <assert.h>
 #include <libgen.h>
 #include <pthread.h>
+#include <regex.h>
 
 #include "utlist.h"
 #include "uthash.h"
 #include "darshan.h"
 #include "darshan-dynamic.h"
+#include "darshan-dxt.h"
 
 #ifndef HAVE_OFF64_T
 typedef int64_t off64_t;
@@ -79,6 +81,8 @@ struct dxt_file_record_ref
 
     segment_info *write_traces;
     segment_info *read_traces;
+
+    char trace_enabled;
 };
 
 /* The dxt_runtime structure maintains necessary state for storing
@@ -101,24 +105,46 @@ struct dxt_mpiio_runtime
     int record_buf_size;
 };
 
-/* dxt read/write instrumentation wrappers for POSIX and MPI-IO */
-void dxt_posix_write(darshan_record_id rec_id, int64_t offset,
-        int64_t length, double start_time, double end_time);
-void dxt_posix_read(darshan_record_id rec_id, int64_t offset,
-        int64_t length, double start_time, double end_time);
-void dxt_mpiio_write(darshan_record_id rec_id, int64_t length,
-        double start_time, double end_time);
-void dxt_mpiio_read(darshan_record_id rec_id, int64_t length,
-        double start_time, double end_time);
+enum dxt_trigger_type
+{
+    DXT_FILE_TRIGGER,
+    DXT_RANK_TRIGGER,
+    DXT_SMALL_IO_TRIGGER,
+    DXT_UNALIGNED_IO_TRIGGER
+};
 
+struct dxt_trigger_info
+{
+    int type;
+    union {
+        struct
+        {
+            regex_t regex;
+        } file;
+        struct
+        {
+            regex_t regex;
+        } rank;
+        struct
+        {
+            double thresh_pct;
+        } small_io;
+        struct
+        {
+            double thresh_pct;
+        } unaligned_io;
+    } u;
+};
+
+/* internal helper routines */
+static int dxt_should_trace_rank(
+    int rank);
+static int dxt_should_trace_file(
+    darshan_record_id rec_id);
 static void check_wr_trace_buf(
     struct dxt_file_record_ref *rec_ref);
 static void check_rd_trace_buf(
     struct dxt_file_record_ref *rec_ref);
-static void dxt_posix_runtime_initialize(
-    void);
-static void dxt_mpiio_runtime_initialize(
-    void);
 static struct dxt_file_record_ref *dxt_posix_track_new_file_record(
     darshan_record_id rec_id);
 static struct dxt_file_record_ref *dxt_mpiio_track_new_file_record(
@@ -128,6 +154,7 @@ static void dxt_posix_cleanup_runtime(
 static void dxt_mpiio_cleanup_runtime(
     void);
 
+/* DXT shutdown routines for darshan-core */
 static void dxt_posix_shutdown(
     MPI_Comm mod_comm, darshan_record_id *shared_recs,
     int shared_rec_count, void **dxt_buf, int *dxt_buf_sz);
@@ -144,78 +171,225 @@ static int dxt_my_rank = -1;
 static int dxt_total_mem = DXT_IO_TRACE_MEM_MAX;
 static int dxt_mem_remaining = 0;
 
+#define MAX_DXT_TRIGGERS 20
+static int num_dxt_triggers = 0;
+static struct dxt_trigger_info dxt_triggers[MAX_DXT_TRIGGERS];
+static int dxt_use_file_triggers = 0;
+static int dxt_use_rank_triggers = 0;
+static int dxt_use_dynamic_triggers = 0;
+static int dxt_trace_all = 0;
+
 #define DXT_LOCK() pthread_mutex_lock(&dxt_runtime_mutex)
 #define DXT_UNLOCK() pthread_mutex_unlock(&dxt_runtime_mutex)
 
+/************************************************************
+ *  DXT routines exposed to Darshan core and other modules  *
+ ************************************************************/
 
-/**********************************************************
- *      Wrappers for DXT I/O functions of interest      *
- **********************************************************/
-
-static void check_wr_trace_buf(struct dxt_file_record_ref *rec_ref)
+void dxt_load_trigger_conf(
+    char *trigger_conf_path)
 {
-    struct dxt_file_record *file_rec = rec_ref->file_rec;
-
-    int write_count = file_rec->write_count;
-    int write_available_buf = rec_ref->write_available_buf;
+    FILE *fp;
+    char *line = NULL;
+    size_t len = 0;
+    char *tok;
+    struct dxt_trigger_info *next_trigger;
+    int ret;
 
-    if (write_count >= write_available_buf) {
-        int write_count_inc;
-        if(write_available_buf == 0)
-            write_count_inc = IO_TRACE_BUF_SIZE;
-        else
-            write_count_inc = write_available_buf;
+    fp = fopen(trigger_conf_path, "r");
+    if(!fp)
+    {
+        darshan_core_fprintf(stderr, "darshan library warning: "\
+            "unable to open DXT trigger config at path %s\n", trigger_conf_path);
+        return;
+    }
 
-        DXT_LOCK();
-        if((write_count_inc * sizeof(segment_info)) > dxt_mem_remaining)
-            write_count_inc = dxt_mem_remaining / sizeof(segment_info);
+    while(getline(&line, &len, fp) != -1)
+    {
+        /* remove newline if present */
+        if(line[strlen(line) - 1] == '\n')
+            line[strlen(line) - 1] = '\0';
 
-        dxt_mem_remaining -= (write_count_inc * sizeof(segment_info));
-        DXT_UNLOCK();
+        next_trigger = &dxt_triggers[num_dxt_triggers];
 
-        if(write_count_inc > 0)
+        /* extract trigger type and parameters */
+        tok = strtok(line, " \t");
+        if(strcmp(tok, "FILE") == 0)
         {
-            write_available_buf += write_count_inc;
-            rec_ref->write_traces =
-                (segment_info *)realloc(rec_ref->write_traces,
-                        write_available_buf * sizeof(segment_info));
-
-            rec_ref->write_available_buf = write_available_buf;
+            next_trigger->type = DXT_FILE_TRIGGER;
+            tok += strlen(tok) + 1;
+            ret = regcomp(&next_trigger->u.file.regex, tok, REG_EXTENDED);
+            if(ret)
+            {
+                darshan_core_fprintf(stderr, "darshan library warning: "\
+                    "unable to compile DXT trigger regex from %s\n", line);
+                continue;
+            }
+            dxt_use_file_triggers = 1;
+        }
+        else if(strcmp(tok, "RANK") == 0)
+        {
+            next_trigger->type = DXT_RANK_TRIGGER;
+            tok += strlen(tok) + 1;
+            ret = regcomp(&next_trigger->u.rank.regex, tok, REG_EXTENDED);
+            if(ret)
+            {
+                darshan_core_fprintf(stderr, "darshan library warning: "\
+                    "unable to compile DXT trigger regex from %s\n", line);
+                continue;
+            }
+            dxt_use_rank_triggers= 1;
+        }
+        else if(strcmp(tok, "SMALL_IO") == 0)
+        {
+            next_trigger->type = DXT_SMALL_IO_TRIGGER;
+            tok += strlen(tok) + 1;
+            next_trigger->u.small_io.thresh_pct = atof(tok);
+            dxt_use_dynamic_triggers= 1;
+        }
+        else if(strcmp(tok, "UNALIGNED_IO") == 0)
+        {
+            next_trigger->type = DXT_UNALIGNED_IO_TRIGGER;
+            tok += strlen(tok) + 1;
+            next_trigger->u.unaligned_io.thresh_pct = atof(tok);
+            dxt_use_dynamic_triggers= 1;
+        }
+        else
+        {
+            darshan_core_fprintf(stderr, "darshan library warning: "\
+                "unknown DXT trigger (%s) found in %s\n", tok, trigger_conf_path);
+            continue;
         }
+        ++num_dxt_triggers;
     }
+
+    fclose(fp);
+    free(line);
+    return;
 }
 
-static void check_rd_trace_buf(struct dxt_file_record_ref *rec_ref)
+void dxt_posix_runtime_initialize()
 {
-    struct dxt_file_record *file_rec = rec_ref->file_rec;
+    /* DXT modules request 0 memory -- buffers will be managed internally by DXT
+     * and passed back to darshan-core at shutdown time to allow DXT more control
+     * over realloc'ing module memory as needed.
+     */
+    int dxt_psx_buf_size = 0;
+    int ret;
+    double tmpfloat;
+    char *envstr;
 
-    int read_count = file_rec->read_count;
-    int read_available_buf = rec_ref->read_available_buf;
+    /* determine whether tracing should be generally disabled/enabled */
+    if(getenv("DXT_ENABLE_IO_TRACE"))
+        dxt_trace_all = 1;
+    else if(getenv("DXT_DISABLE_IO_TRACE"))
+        return;
 
-    if (read_count >= read_available_buf) {
-        int read_count_inc;
-        if(read_available_buf == 0)
-            read_count_inc = IO_TRACE_BUF_SIZE;
-        else
-            read_count_inc = read_available_buf;
+    /* register the DXT module with darshan core */
+    darshan_core_register_module(
+        DXT_POSIX_MOD,
+        &dxt_posix_shutdown,
+        &dxt_psx_buf_size,
+        &dxt_my_rank,
+        NULL);
 
-        DXT_LOCK();
-        if((read_count_inc * sizeof(segment_info)) > dxt_mem_remaining)
-            read_count_inc = dxt_mem_remaining / sizeof(segment_info);
+    /* return if darshan-core allocates an unexpected amount of memory */
+    if(dxt_psx_buf_size != 0)
+    {
+        darshan_core_unregister_module(DXT_POSIX_MOD);
+        return;
+    }
 
-        dxt_mem_remaining -= (read_count_inc * sizeof(segment_info));
+    /* determine whether we should avoid tracing on this rank */
+    if(!dxt_should_trace_rank(dxt_my_rank))
+    {
+        if(!dxt_trace_all && !dxt_use_file_triggers && !dxt_use_dynamic_triggers)
+        {
+            /* nothing to trace, just back out */
+            darshan_core_unregister_module(DXT_POSIX_MOD);
+            return;
+        }
+    }
+    else
+    {
+        dxt_trace_all = 1; /* trace everything */
+    }
+
+    DXT_LOCK();
+    dxt_posix_runtime = malloc(sizeof(*dxt_posix_runtime));
+    if(!dxt_posix_runtime)
+    {
+        darshan_core_unregister_module(DXT_POSIX_MOD);
         DXT_UNLOCK();
+        return;
+    }
+    memset(dxt_posix_runtime, 0, sizeof(*dxt_posix_runtime));
+    dxt_mem_remaining = dxt_total_mem;
+    DXT_UNLOCK();
 
-        if(read_count_inc > 0)
+    return;
+}
+
+void dxt_mpiio_runtime_initialize()
+{
+    /* DXT modules request 0 memory -- buffers will be managed internally by DXT
+     * and passed back to darshan-core at shutdown time to allow DXT more control
+     * over realloc'ing module memory as needed.
+     */
+    int dxt_mpiio_buf_size = 0;
+    int ret;
+    double tmpfloat;
+    char *envstr;
+
+    /* determine whether tracing should be generally disabled/enabled */
+    if(getenv("DXT_ENABLE_IO_TRACE"))
+        dxt_trace_all = 1;
+    else if(getenv("DXT_DISABLE_IO_TRACE"))
+        return;
+
+    /* register the DXT module with darshan core */
+    darshan_core_register_module(
+        DXT_MPIIO_MOD,
+        &dxt_mpiio_shutdown,
+        &dxt_mpiio_buf_size,
+        &dxt_my_rank,
+        NULL);
+
+    /* return if darshan-core allocates an unexpected amount of memory */
+    if(dxt_mpiio_buf_size != 0)
+    {
+        darshan_core_unregister_module(DXT_MPIIO_MOD);
+        return;
+    }
+
+    /* determine whether we should avoid tracing on this rank */
+    if(!dxt_should_trace_rank(dxt_my_rank))
+    {
+        if(!dxt_trace_all && !dxt_use_file_triggers && !dxt_use_dynamic_triggers)
         {
-            read_available_buf += read_count_inc;
-            rec_ref->read_traces =
-                (segment_info *)realloc(rec_ref->read_traces,
-                        read_available_buf * sizeof(segment_info));
-            
-            rec_ref->read_available_buf = read_available_buf;
+            /* nothing to trace, just back out */
+            darshan_core_unregister_module(DXT_MPIIO_MOD);
+            return;
         }
     }
+    else
+    {
+        dxt_trace_all = 1; /* trace everything */
+    }
+
+    DXT_LOCK();
+    dxt_mpiio_runtime = malloc(sizeof(*dxt_mpiio_runtime));
+    if(!dxt_mpiio_runtime)
+    {
+        darshan_core_unregister_module(DXT_MPIIO_MOD);
+        DXT_UNLOCK();
+        return;
+    }
+    memset(dxt_mpiio_runtime, 0, sizeof(*dxt_mpiio_runtime));
+    dxt_mem_remaining = dxt_total_mem; /* XXX is this right? better with memory */
+    DXT_UNLOCK();
+
+    return;
 }
 
 void dxt_posix_write(darshan_record_id rec_id, int64_t offset,
@@ -223,21 +397,37 @@ void dxt_posix_write(darshan_record_id rec_id, int64_t offset,
 {
     struct dxt_file_record_ref* rec_ref = NULL;
     struct dxt_file_record *file_rec;
+    int should_trace_file;
+
+    DXT_LOCK();
 
-    /* make sure dxt posix runtime is initialized properly */
     if(!dxt_posix_runtime)
     {
-        dxt_posix_runtime_initialize();
-        if(!dxt_posix_runtime) return;
+        DXT_UNLOCK();
+        return;
     }
 
     rec_ref = darshan_lookup_record_ref(dxt_posix_runtime->rec_id_hash,
         &rec_id, sizeof(darshan_record_id));
     if(!rec_ref)
     {
+        /* check whether we should actually trace */
+        should_trace_file = dxt_should_trace_file(rec_id);
+        if(!should_trace_file && !dxt_trace_all && !dxt_use_dynamic_triggers)
+        {
+            DXT_UNLOCK();
+            return;
+        }
+
         /* track new dxt file record */
         rec_ref = dxt_posix_track_new_file_record(rec_id);
-        if(!rec_ref) return;
+        if(!rec_ref)
+        {
+            DXT_UNLOCK();
+            return;
+        }
+        if(should_trace_file)
+            rec_ref->trace_enabled = 1;
     }
 
     file_rec = rec_ref->file_rec;
@@ -246,6 +436,7 @@ void dxt_posix_write(darshan_record_id rec_id, int64_t offset,
     {
         /* no more memory for i/o segments ... back out */
         SET_DXT_MOD_PARTIAL_FLAG(DXT_POSIX_MOD);
+        DXT_UNLOCK();
         return;
     }
 
@@ -254,6 +445,8 @@ void dxt_posix_write(darshan_record_id rec_id, int64_t offset,
     rec_ref->write_traces[file_rec->write_count].start_time = start_time;
     rec_ref->write_traces[file_rec->write_count].end_time = end_time;
     file_rec->write_count += 1;
+
+    DXT_UNLOCK();
 }
 
 void dxt_posix_read(darshan_record_id rec_id, int64_t offset,
@@ -261,20 +454,37 @@ void dxt_posix_read(darshan_record_id rec_id, int64_t offset,
 {
     struct dxt_file_record_ref* rec_ref = NULL;
     struct dxt_file_record *file_rec;
+    int should_trace_file;
+
+    DXT_LOCK();
 
-    /* make sure dxt posix runtime is initialized properly */
     if(!dxt_posix_runtime)
     {
-        dxt_posix_runtime_initialize();
-        if(!dxt_posix_runtime) return;
+        DXT_UNLOCK();
+        return;
     }
 
     rec_ref = darshan_lookup_record_ref(dxt_posix_runtime->rec_id_hash,
                 &rec_id, sizeof(darshan_record_id));
-    if (!rec_ref) {
+    if (!rec_ref)
+    {
+        /* check whether we should actually trace */
+        should_trace_file = dxt_should_trace_file(rec_id);
+        if(!should_trace_file && !dxt_trace_all && !dxt_use_dynamic_triggers)
+        {
+            DXT_UNLOCK();
+            return;
+        }
+
         /* track new dxt file record */
         rec_ref = dxt_posix_track_new_file_record(rec_id);
-        if(!rec_ref) return;
+        if(!rec_ref)
+        {
+            DXT_UNLOCK();
+            return;
+        }
+        if(should_trace_file)
+            rec_ref->trace_enabled = 1;
     }
 
     file_rec = rec_ref->file_rec;
@@ -283,6 +493,7 @@ void dxt_posix_read(darshan_record_id rec_id, int64_t offset,
     {
         /* no more memory for i/o segments ... back out */
         SET_DXT_MOD_PARTIAL_FLAG(DXT_POSIX_MOD);
+        DXT_UNLOCK();
         return;
     }
 
@@ -291,6 +502,8 @@ void dxt_posix_read(darshan_record_id rec_id, int64_t offset,
     rec_ref->read_traces[file_rec->read_count].start_time = start_time;
     rec_ref->read_traces[file_rec->read_count].end_time = end_time;
     file_rec->read_count += 1;
+
+    DXT_UNLOCK();
 }
 
 void dxt_mpiio_write(darshan_record_id rec_id, int64_t length,
@@ -298,21 +511,37 @@ void dxt_mpiio_write(darshan_record_id rec_id, int64_t length,
 {
     struct dxt_file_record_ref* rec_ref = NULL;
     struct dxt_file_record *file_rec;
+    int should_trace_file;
+
+    DXT_LOCK();
 
-    /* make sure dxt mpiio runtime is initialized properly */
     if(!dxt_mpiio_runtime)
     {
-        dxt_mpiio_runtime_initialize();
-        if(!dxt_mpiio_runtime) return;
+        DXT_UNLOCK();
+        return;
     }
 
     rec_ref = darshan_lookup_record_ref(dxt_mpiio_runtime->rec_id_hash,
                 &rec_id, sizeof(darshan_record_id));
     if(!rec_ref)
     {
+        /* check whether we should actually trace */
+        should_trace_file = dxt_should_trace_file(rec_id);
+        if(!should_trace_file && !dxt_trace_all && !dxt_use_dynamic_triggers)
+        {
+            DXT_UNLOCK();
+            return;
+        }
+
         /* track new dxt file record */
         rec_ref = dxt_mpiio_track_new_file_record(rec_id);
-        if(!rec_ref) return;
+        if(!rec_ref)
+        {
+            DXT_UNLOCK();
+            return;
+        }
+        if(should_trace_file)
+            rec_ref->trace_enabled = 1;
     }
 
     file_rec = rec_ref->file_rec;
@@ -321,6 +550,7 @@ void dxt_mpiio_write(darshan_record_id rec_id, int64_t length,
     {
         /* no more memory for i/o segments ... back out */
         SET_DXT_MOD_PARTIAL_FLAG(DXT_MPIIO_MOD);
+        DXT_UNLOCK();
         return;
     }
 
@@ -328,6 +558,8 @@ void dxt_mpiio_write(darshan_record_id rec_id, int64_t length,
     rec_ref->write_traces[file_rec->write_count].start_time = start_time;
     rec_ref->write_traces[file_rec->write_count].end_time = end_time;
     file_rec->write_count += 1;
+
+    DXT_UNLOCK();
 }
 
 void dxt_mpiio_read(darshan_record_id rec_id, int64_t length,
@@ -335,21 +567,37 @@ void dxt_mpiio_read(darshan_record_id rec_id, int64_t length,
 {
     struct dxt_file_record_ref* rec_ref = NULL;
     struct dxt_file_record *file_rec;
+    int should_trace_file;
+
+    DXT_LOCK();
 
-    /* make sure dxt mpiio runtime is initialized properly */
     if(!dxt_mpiio_runtime)
     {
-        dxt_mpiio_runtime_initialize();
-        if(!dxt_mpiio_runtime) return;
+        DXT_UNLOCK();
+        return;
     }
 
     rec_ref = darshan_lookup_record_ref(dxt_mpiio_runtime->rec_id_hash,
                 &rec_id, sizeof(darshan_record_id));
     if(!rec_ref)
     {
+        /* check whether we should actually trace */
+        should_trace_file = dxt_should_trace_file(rec_id);
+        if(!should_trace_file && !dxt_trace_all && !dxt_use_dynamic_triggers)
+        {
+            DXT_UNLOCK();
+            return;
+        }
+
         /* track new dxt file record */
         rec_ref = dxt_mpiio_track_new_file_record(rec_id);
-        if(!rec_ref) return;
+        if(!rec_ref)
+        {
+            DXT_UNLOCK();
+            return;
+        }
+        if(should_trace_file)
+            rec_ref->trace_enabled = 1;
     }
 
     file_rec = rec_ref->file_rec;
@@ -358,6 +606,7 @@ void dxt_mpiio_read(darshan_record_id rec_id, int64_t length,
     {
         /* no more memory for i/o segments ... back out */
         SET_DXT_MOD_PARTIAL_FLAG(DXT_MPIIO_MOD);
+        DXT_UNLOCK();
         return;
     }
 
@@ -365,118 +614,222 @@ void dxt_mpiio_read(darshan_record_id rec_id, int64_t length,
     rec_ref->read_traces[file_rec->read_count].start_time = start_time;
     rec_ref->read_traces[file_rec->read_count].end_time = end_time;
     file_rec->read_count += 1;
+
+    DXT_UNLOCK();
 }
 
+static void dxt_posix_filter_dynamic_traces_iterator(void *rec_ref_p, void *user_ptr)
+{
+    struct dxt_file_record_ref *psx_rec_ref, *mpiio_rec_ref;
+    struct darshan_posix_file *(*rec_id_to_psx_file)(darshan_record_id);
+    struct darshan_posix_file *psx_file;
+    int i;
+    int should_keep = 0;
 
-/**********************************************************
- * Internal functions for manipulating DXT module state *
- **********************************************************/
+    psx_rec_ref = (struct dxt_file_record_ref *)rec_ref_p;
+    if(psx_rec_ref->trace_enabled)
+        return; /* we're already tracing this file */
 
-/* initialize internal DXT module data structures and register with darshan-core */
-static void dxt_posix_runtime_initialize()
-{
-    /* DXT modules request 0 memory -- buffers will be managed internally by DXT
-     * and passed back to darshan-core at shutdown time to allow DXT more control
-     * over realloc'ing module memory as needed.
-     */
-    int dxt_psx_buf_size = 0;
-    int ret;
-    double tmpfloat;
-    char *envstr;
+    rec_id_to_psx_file = (struct darshan_posix_file *(*)(darshan_record_id))user_ptr;
+    psx_file = rec_id_to_psx_file(psx_rec_ref->file_rec->base_rec.id);
 
-    /* register the DXT module with darshan core */
-    darshan_core_register_module(
-        DXT_POSIX_MOD,
-        &dxt_posix_shutdown,
-        &dxt_psx_buf_size,
-        &dxt_my_rank,
-        NULL);
+    /* analyze dynamic triggers to determine whether we should keep the record */
+    for(i = 0; i < num_dxt_triggers; i++)
+    {
+        switch(dxt_triggers[i].type)
+        {
+            case DXT_SMALL_IO_TRIGGER:
+            {
+                int total_ops = psx_file->counters[POSIX_WRITES] +
+                    psx_file->counters[POSIX_READS];
+                int small_ops = psx_file->counters[POSIX_SIZE_WRITE_0_100] +
+                    psx_file->counters[POSIX_SIZE_WRITE_100_1K] + 
+                    psx_file->counters[POSIX_SIZE_WRITE_1K_10K] +
+                    psx_file->counters[POSIX_SIZE_READ_0_100] +
+                    psx_file->counters[POSIX_SIZE_READ_100_1K] + 
+                    psx_file->counters[POSIX_SIZE_READ_1K_10K];
+                double small_pct = (small_ops / (double)(total_ops));
+                if(small_pct > dxt_triggers[i].u.small_io.thresh_pct)
+                    should_keep = 1;
+                break;
+            }
+            case DXT_UNALIGNED_IO_TRIGGER:
+            {
+                int total_ops = psx_file->counters[POSIX_WRITES] +
+                    psx_file->counters[POSIX_READS];
+                int unaligned_ops = psx_file->counters[POSIX_FILE_NOT_ALIGNED];
+                double unaligned_pct = (unaligned_ops / (double)(total_ops));
+                if(unaligned_pct > dxt_triggers[i].u.unaligned_io.thresh_pct)
+                    should_keep = 1;
+                break;
+            }
+            default:
+                continue;
+        }
+        if(should_keep)
+            break;
+    }
 
-    /* return if darshan-core allocates an unexpected amount of memory */
-    if(dxt_psx_buf_size != 0)
+    /* drop the record if no dynamic trace triggers occurred */
+    if(!should_keep)
     {
-        darshan_core_unregister_module(DXT_POSIX_MOD);
-        return;
+        printf("DROP RECORD %lu on rank %d\n", psx_file->base_rec.id, dxt_my_rank);
+        /* first check the MPI-IO traces to see if we should drop there */
+        mpiio_rec_ref = darshan_delete_record_ref(&dxt_mpiio_runtime->rec_id_hash,
+            &psx_file->base_rec.id, sizeof(darshan_record_id));
+        if(mpiio_rec_ref)
+        {
+            free(mpiio_rec_ref->write_traces);
+            free(mpiio_rec_ref->read_traces);
+            free(mpiio_rec_ref->file_rec);
+            free(mpiio_rec_ref);
+        }
+
+        /* then delete the POSIX trace records */
+        psx_rec_ref = darshan_delete_record_ref(&dxt_posix_runtime->rec_id_hash,
+            &psx_file->base_rec.id, sizeof(darshan_record_id));
+        if(psx_rec_ref)
+        {
+            free(psx_rec_ref->write_traces);
+            free(psx_rec_ref->read_traces);
+            free(psx_rec_ref->file_rec);
+            free(psx_rec_ref);
+        }
     }
 
+    return;
+}
+
+void dxt_posix_filter_dynamic_traces(
+    struct darshan_posix_file *(*rec_id_to_psx_file)(darshan_record_id))
+{
     DXT_LOCK();
-    dxt_posix_runtime = malloc(sizeof(*dxt_posix_runtime));
-    if(!dxt_posix_runtime)
+
+    if(!dxt_posix_runtime || !dxt_use_dynamic_triggers || dxt_trace_all)
     {
-        darshan_core_unregister_module(DXT_POSIX_MOD);
         DXT_UNLOCK();
         return;
     }
-    memset(dxt_posix_runtime, 0, sizeof(*dxt_posix_runtime));
 
-    /* set the memory quota for DXT, if it has not been initialized */
-    envstr = getenv("DXT_ENABLE_IO_TRACE");
-    if(envstr && dxt_mpiio_runtime == NULL)
-    {
-        ret = sscanf(envstr, "%lf", &tmpfloat);
-        /* silently ignore if the env variable is set poorly */
-        if(ret == 1 && tmpfloat > 0)
-        {
-            dxt_total_mem = tmpfloat * 1024 * 1024; /* convert from MiB */
-        }
-    }
-    dxt_mem_remaining = dxt_total_mem;
+    darshan_iter_record_refs(dxt_posix_runtime->rec_id_hash,
+        dxt_posix_filter_dynamic_traces_iterator, rec_id_to_psx_file);
+
     DXT_UNLOCK();
 
     return;
 }
 
-void dxt_mpiio_runtime_initialize()
+/***********************************
+ *  internal DXT helper routines   *
+ ***********************************/
+
+static int dxt_should_trace_rank(int my_rank)
 {
-    /* DXT modules request 0 memory -- buffers will be managed internally by DXT
-     * and passed back to darshan-core at shutdown time to allow DXT more control
-     * over realloc'ing module memory as needed.
-     */
-    int dxt_mpiio_buf_size = 0;
-    int ret;
-    double tmpfloat;
-    char *envstr;
+    int i;
+    char rank_str[16] = {0};
 
-    /* register the DXT module with darshan core */
-    darshan_core_register_module(
-        DXT_MPIIO_MOD,
-        &dxt_mpiio_shutdown,
-        &dxt_mpiio_buf_size,
-        &dxt_my_rank,
-        NULL);
+    sprintf(rank_str, "%d", my_rank);
 
-    /* return if darshan-core allocates an unexpected amount of memory */
-    if(dxt_mpiio_buf_size != 0)
+    if(!dxt_use_rank_triggers)
+        return(0);
+
+    for(i = 0; i < num_dxt_triggers; i++)
     {
-        darshan_core_unregister_module(DXT_MPIIO_MOD);
-        return;
+        if((dxt_triggers[i].type == DXT_RANK_TRIGGER) &&
+           (regexec(&dxt_triggers[i].u.rank.regex, rank_str, 0, NULL, 0) == 0))
+            return(1);
     }
 
-    DXT_LOCK();
-    dxt_mpiio_runtime = malloc(sizeof(*dxt_mpiio_runtime));
-    if(!dxt_mpiio_runtime)
+    return(0);
+}
+
+static int dxt_should_trace_file(darshan_record_id rec_id)
+{
+    char *rec_name;
+    int i;
+
+    if(!dxt_use_file_triggers)
+        return(0);
+
+    rec_name  = darshan_core_lookup_record_name(rec_id);
+    if(rec_name)
     {
-        darshan_core_unregister_module(DXT_MPIIO_MOD);
-        DXT_UNLOCK();
-        return;
+        /* compare file name against cached triggers to see if we should trace */
+        for(i = 0; i < num_dxt_triggers; i++)
+        {
+            if((dxt_triggers[i].type == DXT_FILE_TRIGGER) &&
+               (regexec(&dxt_triggers[i].u.file.regex, rec_name, 0, NULL, 0) == 0))
+                return(1);
+        }
     }
-    memset(dxt_mpiio_runtime, 0, sizeof(*dxt_mpiio_runtime));
 
-    /* set the memory quota for DXT, if it has not been initialized */
-    envstr = getenv("DXT_ENABLE_IO_TRACE");
-    if(envstr && dxt_posix_runtime == NULL)
-    {
-        ret = sscanf(envstr, "%lf", &tmpfloat);
-        /* silently ignore if the env variable is set poorly */
-        if(ret == 1 && tmpfloat > 0)
+    return(0);
+}
+
+static void check_wr_trace_buf(struct dxt_file_record_ref *rec_ref)
+{
+    struct dxt_file_record *file_rec = rec_ref->file_rec;
+
+    int write_count = file_rec->write_count;
+    int write_available_buf = rec_ref->write_available_buf;
+
+    if (write_count >= write_available_buf) {
+        int write_count_inc;
+        if(write_available_buf == 0)
+            write_count_inc = IO_TRACE_BUF_SIZE;
+        else
+            write_count_inc = write_available_buf;
+
+        DXT_LOCK();
+        if((write_count_inc * sizeof(segment_info)) > dxt_mem_remaining)
+            write_count_inc = dxt_mem_remaining / sizeof(segment_info);
+
+        dxt_mem_remaining -= (write_count_inc * sizeof(segment_info));
+        DXT_UNLOCK();
+
+        if(write_count_inc > 0)
         {
-            dxt_total_mem = tmpfloat * 1024 * 1024; /* convert from MiB */
+            write_available_buf += write_count_inc;
+            rec_ref->write_traces =
+                (segment_info *)realloc(rec_ref->write_traces,
+                        write_available_buf * sizeof(segment_info));
+
+            rec_ref->write_available_buf = write_available_buf;
         }
     }
-    dxt_mem_remaining = dxt_total_mem;
-    DXT_UNLOCK();
+}
 
-    return;
+static void check_rd_trace_buf(struct dxt_file_record_ref *rec_ref)
+{
+    struct dxt_file_record *file_rec = rec_ref->file_rec;
+
+    int read_count = file_rec->read_count;
+    int read_available_buf = rec_ref->read_available_buf;
+
+    if (read_count >= read_available_buf) {
+        int read_count_inc;
+        if(read_available_buf == 0)
+            read_count_inc = IO_TRACE_BUF_SIZE;
+        else
+            read_count_inc = read_available_buf;
+
+        DXT_LOCK();
+        if((read_count_inc * sizeof(segment_info)) > dxt_mem_remaining)
+            read_count_inc = dxt_mem_remaining / sizeof(segment_info);
+
+        dxt_mem_remaining -= (read_count_inc * sizeof(segment_info));
+        DXT_UNLOCK();
+
+        if(read_count_inc > 0)
+        {
+            read_available_buf += read_count_inc;
+            rec_ref->read_traces =
+                (segment_info *)realloc(rec_ref->read_traces,
+                        read_available_buf * sizeof(segment_info));
+            
+            rec_ref->read_available_buf = read_available_buf;
+        }
+    }
 }
 
 static struct dxt_file_record_ref *dxt_posix_track_new_file_record(
@@ -555,6 +908,7 @@ static struct dxt_file_record_ref *dxt_mpiio_track_new_file_record(
 
     rec_ref = malloc(sizeof(*rec_ref));
     if(!rec_ref)
+
     {
         DXT_UNLOCK();
         return(NULL);
@@ -595,7 +949,7 @@ static struct dxt_file_record_ref *dxt_mpiio_track_new_file_record(
     return(rec_ref);
 }
 
-static void dxt_free_record_data(void *rec_ref_p)
+static void dxt_free_record_data(void *rec_ref_p, void *user_ptr)
 {
     struct dxt_file_record_ref *dxt_rec_ref = (struct dxt_file_record_ref *)rec_ref_p;
 
@@ -606,7 +960,8 @@ static void dxt_free_record_data(void *rec_ref_p)
 
 static void dxt_posix_cleanup_runtime()
 {
-    darshan_iter_record_refs(dxt_posix_runtime->rec_id_hash, dxt_free_record_data);
+    darshan_iter_record_refs(dxt_posix_runtime->rec_id_hash,
+        dxt_free_record_data, NULL);
     darshan_clear_record_refs(&(dxt_posix_runtime->rec_id_hash), 1);
 
     free(dxt_posix_runtime);
@@ -617,7 +972,8 @@ static void dxt_posix_cleanup_runtime()
 
 static void dxt_mpiio_cleanup_runtime()
 {
-    darshan_iter_record_refs(dxt_mpiio_runtime->rec_id_hash, dxt_free_record_data);
+    darshan_iter_record_refs(dxt_mpiio_runtime->rec_id_hash,
+        dxt_free_record_data, NULL);
     darshan_clear_record_refs(&(dxt_mpiio_runtime->rec_id_hash), 1);
 
     free(dxt_mpiio_runtime);
@@ -626,12 +982,11 @@ static void dxt_mpiio_cleanup_runtime()
     return;
 }
 
-
 /********************************************************************************
  * shutdown function exported by this module for coordinating with darshan-core *
  ********************************************************************************/
 
-static void dxt_serialize_posix_records(void *rec_ref_p)
+static void dxt_serialize_posix_records(void *rec_ref_p, void *user_ptr)
 {
     struct dxt_file_record_ref *rec_ref = (struct dxt_file_record_ref *)rec_ref_p;
     struct dxt_file_record *file_rec;
@@ -732,7 +1087,8 @@ static void dxt_posix_shutdown(
     dxt_posix_runtime->record_buf_size = 0;
 
     /* iterate all dxt posix records and serialize them to the output buffer */
-    darshan_iter_record_refs(dxt_posix_runtime->rec_id_hash, dxt_serialize_posix_records);
+    darshan_iter_record_refs(dxt_posix_runtime->rec_id_hash,
+        dxt_serialize_posix_records, NULL);
 
     /* set output */
     *dxt_posix_buf = dxt_posix_runtime->record_buf;
@@ -744,7 +1100,7 @@ static void dxt_posix_shutdown(
     return;
 }
 
-static void dxt_serialize_mpiio_records(void *rec_ref_p)
+static void dxt_serialize_mpiio_records(void *rec_ref_p, void *user_ptr)
 {
     struct dxt_file_record_ref *rec_ref = (struct dxt_file_record_ref *)rec_ref_p;
     struct dxt_file_record *file_rec;
@@ -842,7 +1198,8 @@ static void dxt_mpiio_shutdown(
     dxt_mpiio_runtime->record_buf_size = 0;
 
     /* iterate all dxt posix records and serialize them to the output buffer */
-    darshan_iter_record_refs(dxt_mpiio_runtime->rec_id_hash, dxt_serialize_mpiio_records);
+    darshan_iter_record_refs(dxt_mpiio_runtime->rec_id_hash,
+        dxt_serialize_mpiio_records, NULL);
 
     /* set output */ 
     *dxt_mpiio_buf = dxt_mpiio_runtime->record_buf;


=====================================
darshan-runtime/lib/darshan-lustre.c
=====================================
@@ -27,9 +27,9 @@
 static void lustre_runtime_initialize(
     void);
 static void lustre_subtract_shared_rec_size(
-    void *rec_ref_p);
+    void *rec_ref_p, void *user_ptr);
 static void lustre_set_rec_ref_pointers(
-    void *rec_ref_p);
+    void *rec_ref_p, void *user_ptr);
 static int lustre_record_compare(
     const void* a_p, const void* b_p);
 int sort_lustre_records(
@@ -266,7 +266,7 @@ static void lustre_shutdown(
         if (my_rank != 0)
         {
             darshan_iter_record_refs(lustre_runtime->record_id_hash, 
-                &lustre_subtract_shared_rec_size);
+                &lustre_subtract_shared_rec_size, NULL);
         }
     }
 
@@ -282,7 +282,7 @@ static void lustre_shutdown(
     return;
 }
 
-static void lustre_subtract_shared_rec_size(void *rec_ref_p)
+static void lustre_subtract_shared_rec_size(void *rec_ref_p, void *user_ptr)
 {
     struct lustre_record_ref *l_rec_ref = (struct lustre_record_ref *)rec_ref_p;
 
@@ -291,7 +291,7 @@ static void lustre_subtract_shared_rec_size(void *rec_ref_p)
             LUSTRE_RECORD_SIZE( l_rec_ref->record->counters[LUSTRE_STRIPE_WIDTH] );
 }
 
-static void lustre_set_rec_ref_pointers(void *rec_ref_p)
+static void lustre_set_rec_ref_pointers(void *rec_ref_p, void *user_ptr)
 {
     lustre_runtime->record_ref_array[lustre_runtime->record_ref_array_ndx] = rec_ref_p;
     lustre_runtime->record_ref_array_ndx++;
@@ -356,7 +356,7 @@ int sort_lustre_records()
 
     /* build the array of record reference pointers we want to sort */
     darshan_iter_record_refs(lustre_runtime->record_id_hash,
-        &lustre_set_rec_ref_pointers);
+        &lustre_set_rec_ref_pointers, NULL);
 
     /* qsort breaks the hash table, so delete it now to free its memory buffers
      * and prevent later confusion */


=====================================
darshan-runtime/lib/darshan-mdhim.c
=====================================
@@ -578,7 +578,7 @@ static void mdhim_shutdown(
         if (my_rank != 0)
         {
             darshan_iter_record_refs(mdhim_runtime->rec_id_hash,
-                    &mdhim_subtract_shared_rec_size);
+                    &mdhim_subtract_shared_rec_size, NULL);
         }
     }
     *mdhim_buf_sz = mdhim_rec_count * mdhim_runtime->record_buffer_size;


=====================================
darshan-runtime/lib/darshan-mpiio.c
=====================================
@@ -24,6 +24,7 @@
 
 #include "darshan.h"
 #include "darshan-dynamic.h"
+#include "darshan-dxt.h"
 
 DARSHAN_FORWARD_DECL(PMPI_File_close, int, (MPI_File *fh));
 DARSHAN_FORWARD_DECL(PMPI_File_iread_at, int, (MPI_File fh, MPI_Offset offset, void *buf, int count, MPI_Datatype datatype, __D_MPI_REQUEST *request));
@@ -159,7 +160,7 @@ static void mpiio_runtime_initialize(
 static struct mpiio_file_record_ref *mpiio_track_new_file_record(
     darshan_record_id rec_id, const char *path);
 static void mpiio_finalize_file_records(
-    void *rec_ref_p);
+    void *rec_ref_p, void *user_ptr);
 static void mpiio_record_reduction_op(
     void* infile_v, void* inoutfile_v, int *len, MPI_Datatype *datatype);
 static void mpiio_shared_record_variance(
@@ -172,16 +173,9 @@ static void mpiio_shutdown(
     MPI_Comm mod_comm, darshan_record_id *shared_recs,
     int shared_rec_count, void **mpiio_buf, int *mpiio_buf_sz);
 
-/* extern DXT function defs */
-extern void dxt_mpiio_write(darshan_record_id rec_id, int64_t length,
-    double start_time, double end_time);
-extern void dxt_mpiio_read(darshan_record_id rec_id, int64_t length,
-    double start_time, double end_time);
-
 static struct mpiio_runtime *mpiio_runtime = NULL;
 static pthread_mutex_t mpiio_runtime_mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
 static int my_rank = -1;
-static int enable_dxt_io_trace = 0;
 
 #define MPIIO_LOCK() pthread_mutex_lock(&mpiio_runtime_mutex)
 #define MPIIO_UNLOCK() pthread_mutex_unlock(&mpiio_runtime_mutex)
@@ -249,9 +243,7 @@ static int enable_dxt_io_trace = 0;
     PMPI_Type_size(__datatype, &size);  \
     size = size * __count; \
     /* DXT to record detailed read tracing information */ \
-    if(enable_dxt_io_trace) { \
-        dxt_mpiio_read(rec_ref->file_rec->base_rec.id, size, __tm1, __tm2); \
-    } \
+    dxt_mpiio_read(rec_ref->file_rec->base_rec.id, size, __tm1, __tm2); \
     DARSHAN_BUCKET_INC(&(rec_ref->file_rec->counters[MPIIO_SIZE_READ_AGG_0_100]), size); \
     darshan_common_val_counter(&rec_ref->access_root, &rec_ref->access_count, size, \
         &(rec_ref->file_rec->counters[MPIIO_ACCESS1_ACCESS]), \
@@ -281,10 +273,8 @@ static int enable_dxt_io_trace = 0;
     if(!rec_ref) break; \
     PMPI_Type_size(__datatype, &size);  \
     size = size * __count; \
-     /* DXT to record detailed write tracing information */ \
-    if(enable_dxt_io_trace) { \
-        dxt_mpiio_write(rec_ref->file_rec->base_rec.id, size, __tm1, __tm2); \
-    } \
+    /* DXT to record detailed write tracing information */ \
+    dxt_mpiio_write(rec_ref->file_rec->base_rec.id, size, __tm1, __tm2); \
     DARSHAN_BUCKET_INC(&(rec_ref->file_rec->counters[MPIIO_SIZE_WRITE_AGG_0_100]), size); \
     darshan_common_val_counter(&rec_ref->access_root, &rec_ref->access_count, size, \
         &(rec_ref->file_rec->counters[MPIIO_ACCESS1_ACCESS]), \
@@ -1142,10 +1132,8 @@ static void mpiio_runtime_initialize()
     }
     memset(mpiio_runtime, 0, sizeof(*mpiio_runtime));
 
-    /* check if DXT (Darshan extended tracing) should be enabled */
-    if (getenv("DXT_ENABLE_IO_TRACE")) {
-        enable_dxt_io_trace = 1;
-    }
+    /* allow DXT module to initialize if needed */
+    dxt_mpiio_runtime_initialize();
 
     return;
 }
@@ -1198,7 +1186,7 @@ static struct mpiio_file_record_ref *mpiio_track_new_file_record(
     return(rec_ref);
 }
 
-static void mpiio_finalize_file_records(void *rec_ref_p)
+static void mpiio_finalize_file_records(void *rec_ref_p, void *user_ptr)
 {
     struct mpiio_file_record_ref *rec_ref =
         (struct mpiio_file_record_ref *)rec_ref_p;
@@ -1586,7 +1574,8 @@ static void mpiio_shutdown(
     /* perform any final transformations on MPIIO file records before
      * writing them out to log file
      */
-    darshan_iter_record_refs(mpiio_runtime->rec_id_hash, &mpiio_finalize_file_records);
+    darshan_iter_record_refs(mpiio_runtime->rec_id_hash,
+        &mpiio_finalize_file_records, NULL);
 
     /* if there are globally shared files, do a shared file reduction */
     /* NOTE: the shared file reduction is also skipped if the 


=====================================
darshan-runtime/lib/darshan-posix.c
=====================================
@@ -29,6 +29,7 @@
 #include "utlist.h"
 #include "darshan.h"
 #include "darshan-dynamic.h"
+#include "darshan-dxt.h"
 
 #ifndef HAVE_OFF64_T
 typedef int64_t off64_t;
@@ -152,7 +153,7 @@ static void posix_aio_tracker_add(
 static struct posix_aio_tracker* posix_aio_tracker_del(
     int fd, void *aiocbp);
 static void posix_finalize_file_records(
-    void *rec_ref_p);
+    void *rec_ref_p, void *user_ptr);
 static void posix_record_reduction_op(
     void* infile_v, void* inoutfile_v, int *len, MPI_Datatype *datatype);
 static void posix_shared_record_variance(
@@ -165,12 +166,6 @@ static void posix_shutdown(
     MPI_Comm mod_comm, darshan_record_id *shared_recs,
     int shared_rec_count, void **posix_buf, int *posix_buf_sz);
 
-/* extern DXT function defs */
-extern void dxt_posix_write(darshan_record_id rec_id, int64_t offset,
-    int64_t length, double start_time, double end_time);
-extern void dxt_posix_read(darshan_record_id rec_id, int64_t offset,
-    int64_t length, double start_time, double end_time);
-
 /* extern function def for querying record name from a STDIO stream */
 extern char *darshan_stdio_lookup_record_name(FILE *stream);
 
@@ -178,7 +173,6 @@ static struct posix_runtime *posix_runtime = NULL;
 static pthread_mutex_t posix_runtime_mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
 static int my_rank = -1;
 static int darshan_mem_alignment = 1;
-static int enable_dxt_io_trace = 0;
 
 #define POSIX_LOCK() pthread_mutex_lock(&posix_runtime_mutex)
 #define POSIX_UNLOCK() pthread_mutex_unlock(&posix_runtime_mutex)
@@ -259,9 +253,7 @@ static int enable_dxt_io_trace = 0;
     else \
         this_offset = rec_ref->offset; \
     /* DXT to record detailed read tracing information */ \
-    if(enable_dxt_io_trace) { \
-        dxt_posix_read(rec_ref->file_rec->base_rec.id, this_offset, __ret, __tm1, __tm2); \
-    } \
+    dxt_posix_read(rec_ref->file_rec->base_rec.id, this_offset, __ret, __tm1, __tm2); \
     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)) \
@@ -317,9 +309,7 @@ static int enable_dxt_io_trace = 0;
     else \
         this_offset = rec_ref->offset; \
     /* DXT to record detailed write tracing information */ \
-    if(enable_dxt_io_trace) { \
-        dxt_posix_write(rec_ref->file_rec->base_rec.id, this_offset, __ret, __tm1, __tm2); \
-    } \
+    dxt_posix_write(rec_ref->file_rec->base_rec.id, this_offset, __ret, __tm1, __tm2); \
     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)) \
@@ -1506,10 +1496,8 @@ static void posix_runtime_initialize()
     }
     memset(posix_runtime, 0, sizeof(*posix_runtime));
 
-    /* check if DXT (Darshan extended tracing) should be enabled */
-    if (getenv("DXT_ENABLE_IO_TRACE")) {
-        enable_dxt_io_trace = 1;
-    }
+    /* allow DXT module to initialize if needed */
+    dxt_posix_runtime_initialize();
 
     return;
 }
@@ -1618,7 +1606,7 @@ static void posix_aio_tracker_add(int fd, void *aiocbp)
     return;
 }
 
-static void posix_finalize_file_records(void *rec_ref_p)
+static void posix_finalize_file_records(void *rec_ref_p, void *user_ptr)
 {
     struct posix_file_record_ref *rec_ref =
         (struct posix_file_record_ref *)rec_ref_p;
@@ -1971,6 +1959,18 @@ char *darshan_posix_lookup_record_name(int fd)
     return(rec_name);
 }
 
+static struct darshan_posix_file *darshan_posix_rec_id_to_file(darshan_record_id rec_id)
+{
+    struct posix_file_record_ref *rec_ref;
+
+    rec_ref = darshan_lookup_record_ref(posix_runtime->rec_id_hash,
+        &rec_id, sizeof(darshan_record_id));
+    if(rec_ref)
+        return(rec_ref->file_rec);
+    else
+        return(NULL);
+}
+
 /* posix module shutdown benchmark routine */
 void darshan_posix_shutdown_bench_setup(int test_case)
 {
@@ -2067,12 +2067,16 @@ static void posix_shutdown(
     POSIX_LOCK();
     assert(posix_runtime);
 
+    /* allow DXT a chance to filter traces based on dynamic triggers */
+    dxt_posix_filter_dynamic_traces(darshan_posix_rec_id_to_file);
+
     posix_rec_count = posix_runtime->file_rec_count;
 
     /* perform any final transformations on POSIX file records before
      * writing them out to log file
      */
-    darshan_iter_record_refs(posix_runtime->rec_id_hash, &posix_finalize_file_records);
+    darshan_iter_record_refs(posix_runtime->rec_id_hash,
+        &posix_finalize_file_records, NULL);
 
     /* if there are globally shared files, do a shared file reduction */
     /* NOTE: the shared file reduction is also skipped if the 



View it on GitLab: https://xgitlab.cels.anl.gov/darshan/darshan/compare/07e48c1167de94399bce1d230aa114acccdcb227...35a35fe575f618a2c2564c5578fc173dbf03c4ea

-- 
View it on GitLab: https://xgitlab.cels.anl.gov/darshan/darshan/compare/07e48c1167de94399bce1d230aa114acccdcb227...35a35fe575f618a2c2564c5578fc173dbf03c4ea
You're receiving this email because of your account on xgitlab.cels.anl.gov.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.mcs.anl.gov/pipermail/darshan-commits/attachments/20190909/2ac8a0fb/attachment-0001.html>


More information about the Darshan-commits mailing list