#include "json.h"
#include "pmu-events.h"
+struct ordered_ftw_entry {
+ const char *fpath;
+ int typeflag;
+ struct FTW ftwbuf;
+};
+
+struct ordered_ftw_state {
+ struct ordered_ftw_entry *entries;
+ size_t n;
+ size_t max;
+};
+
int verbose;
char *prog;
*/
static FILE *eventsfp;
static char *mapfile;
+static struct ordered_ftw_state *ordered_ftw_state;
+
+static int ordered_ftw_add(const char *fpath,
+ const struct stat *sb __maybe_unused,
+ int typeflag, struct FTW *ftwbuf)
+{
+ struct ordered_ftw_state *state = ordered_ftw_state;
+ struct ordered_ftw_entry *entry;
+
+ if (ftwbuf->level == 0 || ftwbuf->level > 3)
+ return 0;
+
+ /* Grow array if necessary */
+ if (state->n >= state->max) {
+ if (state->max == 0)
+ state->max = 16;
+ else
+ state->max *= 2;
+ state->entries = realloc(state->entries,
+ state->max * sizeof(*state->entries));
+ }
+
+ entry = &state->entries[state->n++];
+ entry->fpath = strdup(fpath);
+ entry->typeflag = typeflag;
+ entry->ftwbuf = *ftwbuf;
+
+ return 0;
+}
+
+static int ordered_ftw_compare(const void *left, const void *right)
+{
+ const struct ordered_ftw_entry *left_entry = left;
+ const struct ordered_ftw_entry *right_entry = right;
+
+ return strcmp(left_entry->fpath, right_entry->fpath);
+}
+
+/*
+ * Wrapper for nftw() that iterates files in ASCII-order to ensure
+ * reproducible output
+ */
+static int ordered_ftw(const char *dirpath,
+ int (*fn)(const char *, int, struct FTW *),
+ int nopenfd, int flags)
+{
+ struct ordered_ftw_state state = { NULL, 0, 0 };
+ size_t i;
+ int rc;
+
+ ordered_ftw_state = &state;
+ rc = nftw(dirpath, ordered_ftw_add, nopenfd, flags);
+ if (rc)
+ goto out;
+
+ qsort(state.entries, state.n, sizeof(*state.entries),
+ ordered_ftw_compare);
+
+ for (i = 0; i < state.n; i++) {
+ rc = fn(state.entries[i].fpath,
+ state.entries[i].typeflag,
+ &state.entries[i].ftwbuf);
+ if (rc)
+ goto out;
+ }
+
+out:
+ for (i = 0; i < state.n; i++)
+ free((char *)state.entries[i].fpath);
+ free(state.entries);;
+
+ return rc;
+}
static int is_leaf_dir(const char *fpath)
{
return 0;
}
-static int preprocess_arch_std_files(const char *fpath, const struct stat *sb,
+static int preprocess_arch_std_files(const char *fpath,
int typeflag, struct FTW *ftwbuf)
{
int level = ftwbuf->level;
int is_file = typeflag == FTW_F;
if (level == 1 && is_file && is_json_file(fpath))
- return json_events(fpath, save_arch_std_events, (void *)sb);
+ return json_events(fpath, save_arch_std_events, NULL);
return 0;
}
-static int process_one_file(const char *fpath, const struct stat *sb,
+static int process_one_file(const char *fpath,
int typeflag, struct FTW *ftwbuf)
{
char *tblname, *bname;
} else
bname = (char *) fpath + ftwbuf->base;
- pr_debug("%s %d %7jd %-20s %s\n",
+ pr_debug("%s %d %-20s %s\n",
is_file ? "f" : is_dir ? "d" : "x",
- level, sb->st_size, bname, fpath);
+ level, bname, fpath);
/* base dir or too deep */
if (level == 0 || level > 4)
*/
maxfds = get_maxfds();
- rc = nftw(ldirname, preprocess_arch_std_files, maxfds, 0);
+ rc = ordered_ftw(ldirname, preprocess_arch_std_files, maxfds, 0);
if (rc)
goto err_processing_std_arch_event_dir;
- rc = nftw(ldirname, process_one_file, maxfds, 0);
+ rc = ordered_ftw(ldirname, process_one_file, maxfds, 0);
if (rc)
goto err_processing_dir;
sprintf(ldirname, "%s/test", start_dirname);
- rc = nftw(ldirname, preprocess_arch_std_files, maxfds, 0);
+ rc = ordered_ftw(ldirname, preprocess_arch_std_files, maxfds, 0);
if (rc)
goto err_processing_std_arch_event_dir;
- rc = nftw(ldirname, process_one_file, maxfds, 0);
+ rc = ordered_ftw(ldirname, process_one_file, maxfds, 0);
if (rc)
goto err_processing_dir;