darshan-posix.c 57.7 KB
Newer Older
1
/*
Shane Snyder's avatar
Shane Snyder committed
2 3 4
 * Copyright (C) 2015 University of Chicago.
 * See COPYRIGHT notice in top-level directory.
 *
5 6
 */

7 8 9
#define _XOPEN_SOURCE 500
#define _GNU_SOURCE

10
#include "darshan-runtime-config.h"
11 12 13 14 15 16 17 18 19 20 21 22 23 24
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdarg.h>
#include <string.h>
#include <time.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/uio.h>
#include <sys/mman.h>
#include <search.h>
#include <assert.h>
25
#include <libgen.h>
26
#include <aio.h>
27
#include <pthread.h>
28

29
#include "utlist.h"
30
#include "darshan.h"
31
#include "darshan-dynamic.h"
32

33
#ifndef HAVE_OFF64_T
34 35
typedef int64_t off64_t;
#endif
36 37 38
#ifndef HAVE_AIOCB64
#define aiocb64 aiocb
#endif
39

40 41
#ifdef DARSHAN_LUSTRE
#include <lustre/lustre_user.h>
42 43
#endif

44 45
DARSHAN_FORWARD_DECL(open, int, (const char *path, int flags, ...));
DARSHAN_FORWARD_DECL(open64, int, (const char *path, int flags, ...));
46 47
DARSHAN_FORWARD_DECL(creat, int, (const char* path, mode_t mode));
DARSHAN_FORWARD_DECL(creat64, int, (const char* path, mode_t mode));
48 49 50 51
DARSHAN_FORWARD_DECL(mkstemp, int, (char *template));
DARSHAN_FORWARD_DECL(mkostemp, int, (char *template, int flags));
DARSHAN_FORWARD_DECL(mkstemps, int, (char *template, int suffixlen));
DARSHAN_FORWARD_DECL(mkostemps, int, (char *template, int suffixlen, int flags));
52 53 54 55 56 57 58 59
DARSHAN_FORWARD_DECL(read, ssize_t, (int fd, void *buf, size_t count));
DARSHAN_FORWARD_DECL(write, ssize_t, (int fd, const void *buf, size_t count));
DARSHAN_FORWARD_DECL(pread, ssize_t, (int fd, void *buf, size_t count, off_t offset));
DARSHAN_FORWARD_DECL(pwrite, ssize_t, (int fd, const void *buf, size_t count, off_t offset));
DARSHAN_FORWARD_DECL(pread64, ssize_t, (int fd, void *buf, size_t count, off64_t offset));
DARSHAN_FORWARD_DECL(pwrite64, ssize_t, (int fd, const void *buf, size_t count, off64_t offset));
DARSHAN_FORWARD_DECL(readv, ssize_t, (int fd, const struct iovec *iov, int iovcnt));
DARSHAN_FORWARD_DECL(writev, ssize_t, (int fd, const struct iovec *iov, int iovcnt));
60 61
DARSHAN_FORWARD_DECL(lseek, off_t, (int fd, off_t offset, int whence));
DARSHAN_FORWARD_DECL(lseek64, off64_t, (int fd, off64_t offset, int whence));
62 63 64 65 66 67
DARSHAN_FORWARD_DECL(__xstat, int, (int vers, const char* path, struct stat *buf));
DARSHAN_FORWARD_DECL(__xstat64, int, (int vers, const char* path, struct stat64 *buf));
DARSHAN_FORWARD_DECL(__lxstat, int, (int vers, const char* path, struct stat *buf));
DARSHAN_FORWARD_DECL(__lxstat64, int, (int vers, const char* path, struct stat64 *buf));
DARSHAN_FORWARD_DECL(__fxstat, int, (int vers, int fd, struct stat *buf));
DARSHAN_FORWARD_DECL(__fxstat64, int, (int vers, int fd, struct stat64 *buf));
Shane Snyder's avatar
Shane Snyder committed
68 69
DARSHAN_FORWARD_DECL(mmap, void*, (void *addr, size_t length, int prot, int flags, int fd, off_t offset));
DARSHAN_FORWARD_DECL(mmap64, void*, (void *addr, size_t length, int prot, int flags, int fd, off64_t offset));
70 71
DARSHAN_FORWARD_DECL(fsync, int, (int fd));
DARSHAN_FORWARD_DECL(fdatasync, int, (int fd));
72
DARSHAN_FORWARD_DECL(close, int, (int fd));
73 74 75 76 77 78 79 80
DARSHAN_FORWARD_DECL(aio_read, int, (struct aiocb *aiocbp));
DARSHAN_FORWARD_DECL(aio_write, int, (struct aiocb *aiocbp));
DARSHAN_FORWARD_DECL(aio_read64, int, (struct aiocb64 *aiocbp));
DARSHAN_FORWARD_DECL(aio_write64, int, (struct aiocb64 *aiocbp));
DARSHAN_FORWARD_DECL(aio_return, ssize_t, (struct aiocb *aiocbp));
DARSHAN_FORWARD_DECL(aio_return64, ssize_t, (struct aiocb64 *aiocbp));
DARSHAN_FORWARD_DECL(lio_listio, int, (int mode, struct aiocb *const aiocb_list[], int nitems, struct sigevent *sevp));
DARSHAN_FORWARD_DECL(lio_listio64, int, (int mode, struct aiocb64 *const aiocb_list[], int nitems, struct sigevent *sevp));
81

82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
/* The posix_file_record_ref 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_rec'. This metadata
 * assists with the instrumenting of specific statistics in the file record.
 *
 * 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_record_ref
 * struct with each darshan_posix_file struct in order to track this information
 * (i.e., the mapping between posix_file_record_ref structs to darshan_posix_file
 * structs is one-to-one).
 *
 * NOTE: we use the 'darshan_record_ref' interface (in darshan-common) to
 * associate different types of handles with this posix_file_record_ref struct.
 * This allows us to index this struct (and the underlying file record) by using
 * either the corresponding Darshan record identifier (derived from the filename)
100 101
 * or by a generated file descriptor, for instance. Note that, while there should
 * only be a single Darshan record identifier that indexes a posix_file_record_ref,
102 103
 * there could be multiple open file descriptors that index it.
 */
104
struct posix_file_record_ref
105
{
106
    struct darshan_posix_file *file_rec;
107 108 109
    int64_t offset;
    int64_t last_byte_read;
    int64_t last_byte_written;
Shane Snyder's avatar
Shane Snyder committed
110
    enum darshan_io_type last_io_type;
111 112 113
    double last_meta_end;
    double last_read_end;
    double last_write_end;
114
    void *access_root;
115
    int access_count;
116
    void *stride_root;
117
    int stride_count;
118
    struct posix_aio_tracker* aio_list;
119
    int fs_type; /* same as darshan_fs_info->fs_type */
120 121
};

122 123 124 125
/* The posix_runtime structure maintains necessary state for storing
 * POSIX file records and for coordinating with darshan-core at 
 * shutdown time.
 */
126 127
struct posix_runtime
{
128 129 130
    void *rec_id_hash;
    void *fd_hash;
    int file_rec_count;
131 132
};

133 134 135 136 137
/* struct to track information about aio operations in flight */
struct posix_aio_tracker
{
    double tm1;
    void *aiocbp;
138
    struct posix_aio_tracker *next;
139
};
140

141 142 143
static void posix_runtime_initialize(
    void);
static struct posix_file_record_ref *posix_track_new_file_record(
144 145 146
    darshan_record_id rec_id, const char *path);
static void posix_instrument_fs_data(
    int fs_type, const char *path, int fd);
147 148 149 150
static void posix_aio_tracker_add(
    int fd, void *aiocbp);
static struct posix_aio_tracker* posix_aio_tracker_del(
    int fd, void *aiocbp);
151 152
static void posix_finalize_file_records(
    void *rec_ref_p);
153 154 155 156 157
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);
158
static void posix_cleanup_runtime(
159
    void);
160 161

static void posix_shutdown(
162
    MPI_Comm mod_comm, darshan_record_id *shared_recs,
163
    int shared_rec_count, void **posix_buf, int *posix_buf_sz);
164

165
#ifdef DARSHAN_LUSTRE
166 167 168
/* XXX modules don't expose an API for other modules, so use extern to get
 * Lustre instrumentation function
 */
169
extern void darshan_instrument_lustre_file(const char *filepath, int fd);
170
#endif
171

172 173 174 175 176 177
static struct posix_runtime *posix_runtime = NULL;
static pthread_mutex_t posix_runtime_mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
static int instrumentation_disabled = 0;
static int my_rank = -1;
static int darshan_mem_alignment = 1;

178 179 180
#define POSIX_LOCK() pthread_mutex_lock(&posix_runtime_mutex)
#define POSIX_UNLOCK() pthread_mutex_unlock(&posix_runtime_mutex)

181 182 183 184 185 186 187 188 189 190 191 192
#define POSIX_PRE_RECORD() do { \
    POSIX_LOCK(); \
    if(!posix_runtime && !instrumentation_disabled) posix_runtime_initialize(); \
    if(!posix_runtime) { \
        POSIX_UNLOCK(); \
        return(ret); \
    } \
} while(0)

#define POSIX_POST_RECORD() do { \
    POSIX_UNLOCK(); \
} while(0)
193

Philip Carns's avatar
Philip Carns committed
194
#define POSIX_RECORD_OPEN(__ret, __path, __mode, __tm1, __tm2) do { \
195
    darshan_record_id rec_id; \
196 197
    struct posix_file_record_ref *rec_ref; \
    char *newpath; \
198
    if(__ret < 0) break; \
199 200 201 202 203 204 205
    newpath = darshan_clean_file_path(__path); \
    if(!newpath) newpath = (char *)__path; \
    if(darshan_core_excluded_path(newpath)) { \
        if(newpath != __path) free(newpath); \
        break; \
    } \
    rec_id = darshan_core_gen_record_id(newpath); \
206
    rec_ref = darshan_lookup_record_ref(posix_runtime->rec_id_hash, &rec_id, sizeof(darshan_record_id)); \
207
    if(!rec_ref) rec_ref = posix_track_new_file_record(rec_id, newpath); \
208
    if(!rec_ref) { \
209 210
        if(newpath != __path) free(newpath); \
        break; \
211
    } \
212
    if(__mode) \
213 214 215 216
        rec_ref->file_rec->counters[POSIX_MODE] = __mode; \
    rec_ref->offset = 0; \
    rec_ref->last_byte_written = 0; \
    rec_ref->last_byte_read = 0; \
217
    rec_ref->file_rec->counters[POSIX_OPENS] += 1; \
218 219
    if(rec_ref->file_rec->fcounters[POSIX_F_OPEN_TIMESTAMP] == 0 || \
     rec_ref->file_rec->fcounters[POSIX_F_OPEN_TIMESTAMP] > __tm1) \
220 221 222
        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); \
223
    darshan_add_record_ref(&(posix_runtime->fd_hash), &__ret, sizeof(int), rec_ref); \
224
    posix_instrument_fs_data(rec_ref->fs_type, newpath, __ret); \
225
    if(newpath != __path) free(newpath); \
226 227
} while(0)

228
#define POSIX_RECORD_READ(__ret, __fd, __pread_flag, __pread_offset, __aligned, __tm1, __tm2) do { \
229
    struct posix_file_record_ref* rec_ref; \
230
    size_t stride; \
231
    int64_t this_offset; \
232
    int64_t file_alignment; \
233 234
    double __elapsed = __tm2-__tm1; \
    if(__ret < 0) break; \
235 236
    rec_ref = darshan_lookup_record_ref(posix_runtime->fd_hash, &(__fd), sizeof(int)); \
    if(!rec_ref) break; \
237
    if(__pread_flag) \
238 239
        this_offset = __pread_offset; \
    else \
240 241 242 243 244 245 246 247
        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; \
248
    else \
249
        stride = 0; \
250 251 252 253 254
    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; \
255
    rec_ref->file_rec->counters[POSIX_READS] += 1; \
256 257 258 259 260 261 262
    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])); \
263
    if(!__aligned) \
264 265
        rec_ref->file_rec->counters[POSIX_MEM_NOT_ALIGNED] += 1; \
    file_alignment = rec_ref->file_rec->counters[POSIX_FILE_ALIGNMENT]; \
266
    if(file_alignment > 0 && (this_offset % file_alignment) != 0) \
267 268 269 270
        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; \
271 272
    if(rec_ref->file_rec->fcounters[POSIX_F_READ_START_TIMESTAMP] == 0 || \
     rec_ref->file_rec->fcounters[POSIX_F_READ_START_TIMESTAMP] > __tm1) \
273 274 275 276 277 278 279
        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); \
280 281
} while(0)

282
#define POSIX_RECORD_WRITE(__ret, __fd, __pwrite_flag, __pwrite_offset, __aligned, __tm1, __tm2) do { \
283
    struct posix_file_record_ref* rec_ref; \
284
    size_t stride; \
285
    int64_t this_offset; \
286
    int64_t file_alignment; \
287 288
    double __elapsed = __tm2-__tm1; \
    if(__ret < 0) break; \
289 290
    rec_ref = darshan_lookup_record_ref(posix_runtime->fd_hash, &__fd, sizeof(int)); \
    if(!rec_ref) break; \
291
    if(__pwrite_flag) \
292 293
        this_offset = __pwrite_offset; \
    else \
294 295 296 297 298 299 300 301
        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; \
302
    else \
303
        stride = 0; \
304 305 306 307 308
    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; \
309
    rec_ref->file_rec->counters[POSIX_WRITES] += 1; \
310 311 312 313 314 315 316
    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])); \
317
    if(!__aligned) \
318 319
        rec_ref->file_rec->counters[POSIX_MEM_NOT_ALIGNED] += 1; \
    file_alignment = rec_ref->file_rec->counters[POSIX_FILE_ALIGNMENT]; \
320
    if(file_alignment > 0 && (this_offset % file_alignment) != 0) \
321 322 323 324
        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; \
325 326
    if(rec_ref->file_rec->fcounters[POSIX_F_WRITE_START_TIMESTAMP] == 0 || \
     rec_ref->file_rec->fcounters[POSIX_F_WRITE_START_TIMESTAMP] > __tm1) \
327 328 329 330 331 332 333
        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); \
334
} while(0)
335

336
#define POSIX_LOOKUP_RECORD_STAT(__path, __statbuf, __tm1, __tm2) do { \
337
    darshan_record_id rec_id; \
338 339 340 341 342 343
    struct posix_file_record_ref* rec_ref; \
    char *newpath = darshan_clean_file_path(__path); \
    if(!newpath) newpath = (char *)__path; \
    if(darshan_core_excluded_path(newpath)) { \
        if(newpath != __path) free(newpath); \
        break; \
344
    } \
345 346
    rec_id = darshan_core_gen_record_id(newpath); \
    rec_ref = darshan_lookup_record_ref(posix_runtime->rec_id_hash, &rec_id, sizeof(darshan_record_id)); \
347
    if(!rec_ref) rec_ref = posix_track_new_file_record(rec_id, newpath); \
348
    if(newpath != __path) free(newpath); \
349 350
    if(rec_ref) { \
        POSIX_RECORD_STAT(rec_ref, __statbuf, __tm1, __tm2); \
351 352 353
    } \
} while(0)

354 355 356 357
#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); \
358 359
} while(0)

360

361 362 363 364
/**********************************************************
 *      Wrappers for POSIX I/O functions of interest      * 
 **********************************************************/

365
int DARSHAN_DECL(open)(const char *path, int flags, ...)
366 367 368 369 370
{
    int mode = 0;
    int ret;
    double tm1, tm2;

371 372
    MAP_OR_FAIL(open);

373
    if(flags & O_CREAT) 
374 375 376 377 378 379
    {
        va_list arg;
        va_start(arg, flags);
        mode = va_arg(arg, int);
        va_end(arg);

380
        tm1 = darshan_core_wtime();
381
        ret = __real_open(path, flags, mode);
382
        tm2 = darshan_core_wtime();
383 384 385
    }
    else
    {
386
        tm1 = darshan_core_wtime();
387
        ret = __real_open(path, flags);
388
        tm2 = darshan_core_wtime();
389 390
    }

391
    POSIX_PRE_RECORD();
Philip Carns's avatar
Philip Carns committed
392
    POSIX_RECORD_OPEN(ret, path, mode, tm1, tm2);
393
    POSIX_POST_RECORD();
394 395 396 397

    return(ret);
}

Shane Snyder's avatar
Shane Snyder committed
398 399 400 401 402 403
int DARSHAN_DECL(open64)(const char *path, int flags, ...)
{
    int mode = 0;
    int ret;
    double tm1, tm2;

404
    MAP_OR_FAIL(open64);
Shane Snyder's avatar
Shane Snyder committed
405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423

    if(flags & O_CREAT)
    {
        va_list arg;
        va_start(arg, flags);
        mode = va_arg(arg, int);
        va_end(arg);

        tm1 = darshan_core_wtime();
        ret = __real_open64(path, flags, mode);
        tm2 = darshan_core_wtime();
    }
    else
    {
        tm1 = darshan_core_wtime();
        ret = __real_open64(path, flags);
        tm2 = darshan_core_wtime();
    }

424
    POSIX_PRE_RECORD();
Philip Carns's avatar
Philip Carns committed
425
    POSIX_RECORD_OPEN(ret, path, mode, tm1, tm2);
426
    POSIX_POST_RECORD();
427 428 429 430 431 432 433 434 435 436 437 438 439 440 441

    return(ret);
}

int DARSHAN_DECL(creat)(const char* path, mode_t mode)
{
    int ret;
    double tm1, tm2;

    MAP_OR_FAIL(creat);

    tm1 = darshan_core_wtime();
    ret = __real_creat(path, mode);
    tm2 = darshan_core_wtime();

442
    POSIX_PRE_RECORD();
Philip Carns's avatar
Philip Carns committed
443
    POSIX_RECORD_OPEN(ret, path, mode, tm1, tm2);
444
    POSIX_POST_RECORD();
445 446 447 448 449 450 451 452 453 454

    return(ret);
}

int DARSHAN_DECL(creat64)(const char* path, mode_t mode)
{
    int ret;
    double tm1, tm2;

    MAP_OR_FAIL(creat64);
Shane Snyder's avatar
Shane Snyder committed
455

456 457 458 459
    tm1 = darshan_core_wtime();
    ret = __real_creat64(path, mode);
    tm2 = darshan_core_wtime();

460
    POSIX_PRE_RECORD();
Philip Carns's avatar
Philip Carns committed
461
    POSIX_RECORD_OPEN(ret, path, mode, tm1, tm2);
462
    POSIX_POST_RECORD();
463 464 465 466

    return(ret);
}

467 468 469 470 471 472 473 474 475 476 477
int DARSHAN_DECL(mkstemp)(char* template)
{
    int ret;
    double tm1, tm2;

    MAP_OR_FAIL(mkstemp);

    tm1 = darshan_core_wtime();
    ret = __real_mkstemp(template);
    tm2 = darshan_core_wtime();

478
    POSIX_PRE_RECORD();
Philip Carns's avatar
Philip Carns committed
479
    POSIX_RECORD_OPEN(ret, template, 0, tm1, tm2);
480
    POSIX_POST_RECORD();
481 482 483 484 485 486 487 488 489 490 491 492 493 494 495

    return(ret);
}

int DARSHAN_DECL(mkostemp)(char* template, int flags)
{
    int ret;
    double tm1, tm2;

    MAP_OR_FAIL(mkostemp);

    tm1 = darshan_core_wtime();
    ret = __real_mkostemp(template, flags);
    tm2 = darshan_core_wtime();

496
    POSIX_PRE_RECORD();
Philip Carns's avatar
Philip Carns committed
497
    POSIX_RECORD_OPEN(ret, template, 0, tm1, tm2);
498
    POSIX_POST_RECORD();
499 500 501 502 503 504 505 506 507 508 509 510 511 512 513

    return(ret);
}

int DARSHAN_DECL(mkstemps)(char* template, int suffixlen)
{
    int ret;
    double tm1, tm2;

    MAP_OR_FAIL(mkstemps);

    tm1 = darshan_core_wtime();
    ret = __real_mkstemps(template, suffixlen);
    tm2 = darshan_core_wtime();

514
    POSIX_PRE_RECORD();
Philip Carns's avatar
Philip Carns committed
515
    POSIX_RECORD_OPEN(ret, template, 0, tm1, tm2);
516
    POSIX_POST_RECORD();
517 518 519 520 521 522 523 524 525 526 527 528 529 530 531

    return(ret);
}

int DARSHAN_DECL(mkostemps)(char* template, int suffixlen, int flags)
{
    int ret;
    double tm1, tm2;

    MAP_OR_FAIL(mkostemps);

    tm1 = darshan_core_wtime();
    ret = __real_mkostemps(template, suffixlen, flags);
    tm2 = darshan_core_wtime();

532
    POSIX_PRE_RECORD();
Philip Carns's avatar
Philip Carns committed
533
    POSIX_RECORD_OPEN(ret, template, 0, tm1, tm2);
534
    POSIX_POST_RECORD();
535 536 537 538

    return(ret);
}

539 540 541 542 543 544
ssize_t DARSHAN_DECL(read)(int fd, void *buf, size_t count)
{
    ssize_t ret;
    int aligned_flag = 0;
    double tm1, tm2;

Shane Snyder's avatar
Shane Snyder committed
545
    MAP_OR_FAIL(read);
546

547
    if((unsigned long)buf % darshan_mem_alignment == 0) aligned_flag = 1;
548 549 550 551 552

    tm1 = darshan_core_wtime();
    ret = __real_read(fd, buf, count);
    tm2 = darshan_core_wtime();

553
    POSIX_PRE_RECORD();
Philip Carns's avatar
Philip Carns committed
554
    POSIX_RECORD_READ(ret, fd, 0, 0, aligned_flag, tm1, tm2);
555
    POSIX_POST_RECORD();
556 557 558 559 560 561 562 563 564 565 566 567

    return(ret);
}

ssize_t DARSHAN_DECL(write)(int fd, const void *buf, size_t count)
{
    ssize_t ret;
    int aligned_flag = 0;
    double tm1, tm2;

    MAP_OR_FAIL(write);

568
    if((unsigned long)buf % darshan_mem_alignment == 0) aligned_flag = 1;
569 570 571 572 573

    tm1 = darshan_core_wtime();
    ret = __real_write(fd, buf, count);
    tm2 = darshan_core_wtime();

574
    POSIX_PRE_RECORD();
Philip Carns's avatar
Philip Carns committed
575
    POSIX_RECORD_WRITE(ret, fd, 0, 0, aligned_flag, tm1, tm2);
576
    POSIX_POST_RECORD();
577 578 579 580 581 582 583 584 585 586 587 588

    return(ret);
}

ssize_t DARSHAN_DECL(pread)(int fd, void *buf, size_t count, off_t offset)
{
    ssize_t ret;
    int aligned_flag = 0;
    double tm1, tm2;

    MAP_OR_FAIL(pread);

589
    if((unsigned long)buf % darshan_mem_alignment == 0) aligned_flag = 1;
590 591 592 593 594

    tm1 = darshan_core_wtime();
    ret = __real_pread(fd, buf, count, offset);
    tm2 = darshan_core_wtime();

595
    POSIX_PRE_RECORD();
Philip Carns's avatar
Philip Carns committed
596
    POSIX_RECORD_READ(ret, fd, 1, offset, aligned_flag, tm1, tm2);
597
    POSIX_POST_RECORD();
598 599 600 601 602 603 604 605 606 607 608 609

    return(ret);
}

ssize_t DARSHAN_DECL(pwrite)(int fd, const void *buf, size_t count, off_t offset)
{
    ssize_t ret;
    int aligned_flag = 0;
    double tm1, tm2;

    MAP_OR_FAIL(pwrite);

610
    if((unsigned long)buf % darshan_mem_alignment == 0) aligned_flag = 1;
611 612 613 614 615

    tm1 = darshan_core_wtime();
    ret = __real_pwrite(fd, buf, count, offset);
    tm2 = darshan_core_wtime();

616
    POSIX_PRE_RECORD();
Philip Carns's avatar
Philip Carns committed
617
    POSIX_RECORD_WRITE(ret, fd, 1, offset, aligned_flag, tm1, tm2);
618
    POSIX_POST_RECORD();
619 620 621 622 623 624 625 626 627 628 629 630

    return(ret);
}

ssize_t DARSHAN_DECL(pread64)(int fd, void *buf, size_t count, off64_t offset)
{
    ssize_t ret;
    int aligned_flag = 0;
    double tm1, tm2;

    MAP_OR_FAIL(pread64);

631
    if((unsigned long)buf % darshan_mem_alignment == 0) aligned_flag = 1;
632 633 634 635 636

    tm1 = darshan_core_wtime();
    ret = __real_pread64(fd, buf, count, offset);
    tm2 = darshan_core_wtime();

637
    POSIX_PRE_RECORD();
Philip Carns's avatar
Philip Carns committed
638
    POSIX_RECORD_READ(ret, fd, 1, offset, aligned_flag, tm1, tm2);
639
    POSIX_POST_RECORD();
640 641 642 643 644 645 646 647 648 649 650 651

    return(ret);
}

ssize_t DARSHAN_DECL(pwrite64)(int fd, const void *buf, size_t count, off64_t offset)
{
    ssize_t ret;
    int aligned_flag = 0;
    double tm1, tm2;

    MAP_OR_FAIL(pwrite64);

652
    if((unsigned long)buf % darshan_mem_alignment == 0) aligned_flag = 1;
653 654 655 656 657

    tm1 = darshan_core_wtime();
    ret = __real_pwrite64(fd, buf, count, offset);
    tm2 = darshan_core_wtime();

658
    POSIX_PRE_RECORD();
Philip Carns's avatar
Philip Carns committed
659
    POSIX_RECORD_WRITE(ret, fd, 1, offset, aligned_flag, tm1, tm2);
660
    POSIX_POST_RECORD();
661 662 663 664 665 666 667

    return(ret);
}

ssize_t DARSHAN_DECL(readv)(int fd, const struct iovec *iov, int iovcnt)
{
    ssize_t ret;
668
    int aligned_flag = 1;
669 670 671 672
    int i;
    double tm1, tm2;

    MAP_OR_FAIL(readv);
673

674 675 676 677
    for(i=0; i<iovcnt; i++)
    {
        if(((unsigned long)iov[i].iov_base % darshan_mem_alignment) != 0)
            aligned_flag = 0;
678
    }
679 680 681 682 683

    tm1 = darshan_core_wtime();
    ret = __real_readv(fd, iov, iovcnt);
    tm2 = darshan_core_wtime();

684
    POSIX_PRE_RECORD();
Philip Carns's avatar
Philip Carns committed
685
    POSIX_RECORD_READ(ret, fd, 0, 0, aligned_flag, tm1, tm2);
686
    POSIX_POST_RECORD();
687 688 689 690 691 692 693

    return(ret);
}

ssize_t DARSHAN_DECL(writev)(int fd, const struct iovec *iov, int iovcnt)
{
    ssize_t ret;
694
    int aligned_flag = 1;
695 696 697 698
    int i;
    double tm1, tm2;

    MAP_OR_FAIL(writev);
699

700 701 702 703
    for(i=0; i<iovcnt; i++)
    {
        if(((unsigned long)iov[i].iov_base % darshan_mem_alignment) != 0)
            aligned_flag = 0;
704
    }
705 706 707 708 709

    tm1 = darshan_core_wtime();
    ret = __real_writev(fd, iov, iovcnt);
    tm2 = darshan_core_wtime();

710
    POSIX_PRE_RECORD();
Philip Carns's avatar
Philip Carns committed
711
    POSIX_RECORD_WRITE(ret, fd, 0, 0, aligned_flag, tm1, tm2);
712
    POSIX_POST_RECORD();
713 714 715 716 717 718 719

    return(ret);
}

off_t DARSHAN_DECL(lseek)(int fd, off_t offset, int whence)
{
    off_t ret;
720
    struct posix_file_record_ref *rec_ref;
721 722 723 724 725 726 727 728 729 730
    double tm1, tm2;

    MAP_OR_FAIL(lseek);

    tm1 = darshan_core_wtime();
    ret = __real_lseek(fd, offset, whence);
    tm2 = darshan_core_wtime();

    if(ret >= 0)
    {
731
        POSIX_PRE_RECORD();
732 733
        rec_ref = darshan_lookup_record_ref(posix_runtime->fd_hash, &fd, sizeof(int));
        if(rec_ref)
734
        {
735
            rec_ref->offset = ret;
736
            DARSHAN_TIMER_INC_NO_OVERLAP(
737 738 739
                rec_ref->file_rec->fcounters[POSIX_F_META_TIME],
                tm1, tm2, rec_ref->last_meta_end);
            rec_ref->file_rec->counters[POSIX_SEEKS] += 1;
740
        }
741
        POSIX_POST_RECORD();
742 743 744 745 746 747 748 749
    }

    return(ret);
}

off_t DARSHAN_DECL(lseek64)(int fd, off_t offset, int whence)
{
    off_t ret;
750
    struct posix_file_record_ref *rec_ref;
751 752 753 754 755 756 757 758 759 760
    double tm1, tm2;

    MAP_OR_FAIL(lseek64);

    tm1 = darshan_core_wtime();
    ret = __real_lseek64(fd, offset, whence);
    tm2 = darshan_core_wtime();

    if(ret >= 0)
    {
761
        POSIX_PRE_RECORD();
762 763
        rec_ref = darshan_lookup_record_ref(posix_runtime->fd_hash, &fd, sizeof(int));
        if(rec_ref)
764
        {
765
            rec_ref->offset = ret;
766
            DARSHAN_TIMER_INC_NO_OVERLAP(
767 768 769
                rec_ref->file_rec->fcounters[POSIX_F_META_TIME],
                tm1, tm2, rec_ref->last_meta_end);
            rec_ref->file_rec->counters[POSIX_SEEKS] += 1;
770
        }
771
        POSIX_POST_RECORD();
772 773 774 775 776
    }

    return(ret);
}

777 778 779 780 781 782 783 784 785 786 787 788 789 790
int DARSHAN_DECL(__xstat)(int vers, const char *path, struct stat *buf)
{
    int ret;
    double tm1, tm2;

    MAP_OR_FAIL(__xstat);

    tm1 = darshan_core_wtime();
    ret = __real___xstat(vers, path, buf);
    tm2 = darshan_core_wtime();

    if(ret < 0 || !S_ISREG(buf->st_mode))
        return(ret);

791
    POSIX_PRE_RECORD();
792
    POSIX_LOOKUP_RECORD_STAT(path, buf, tm1, tm2);
793
    POSIX_POST_RECORD();
794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811

    return(ret);
}

int DARSHAN_DECL(__xstat64)(int vers, const char *path, struct stat64 *buf)
{
    int ret;
    double tm1, tm2;

    MAP_OR_FAIL(__xstat64);

    tm1 = darshan_core_wtime();
    ret = __real___xstat64(vers, path, buf);
    tm2 = darshan_core_wtime();

    if(ret < 0 || !S_ISREG(buf->st_mode))
        return(ret);

812
    POSIX_PRE_RECORD();
813
    POSIX_LOOKUP_RECORD_STAT(path, buf, tm1, tm2);
814
    POSIX_POST_RECORD();
815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832

    return(ret);
}

int DARSHAN_DECL(__lxstat)(int vers, const char *path, struct stat *buf)
{
    int ret;
    double tm1, tm2;

    MAP_OR_FAIL(__lxstat);

    tm1 = darshan_core_wtime();
    ret = __real___lxstat(vers, path, buf);
    tm2 = darshan_core_wtime();

    if(ret < 0 || !S_ISREG(buf->st_mode))
        return(ret);

833
    POSIX_PRE_RECORD();
834
    POSIX_LOOKUP_RECORD_STAT(path, buf, tm1, tm2);
835
    POSIX_POST_RECORD();
836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853

    return(ret);
}

int DARSHAN_DECL(__lxstat64)(int vers, const char *path, struct stat64 *buf)
{
    int ret;
    double tm1, tm2;

    MAP_OR_FAIL(__lxstat64);

    tm1 = darshan_core_wtime();
    ret = __real___lxstat64(vers, path, buf);
    tm2 = darshan_core_wtime();

    if(ret < 0 || !S_ISREG(buf->st_mode))
        return(ret);

854
    POSIX_PRE_RECORD();
855
    POSIX_LOOKUP_RECORD_STAT(path, buf, tm1, tm2);
856
    POSIX_POST_RECORD();
857 858 859 860 861 862 863

    return(ret);
}

int DARSHAN_DECL(__fxstat)(int vers, int fd, struct stat *buf)
{
    int ret;
864
    struct posix_file_record_ref *rec_ref;
865 866 867 868 869 870 871 872 873 874 875
    double tm1, tm2;

    MAP_OR_FAIL(__fxstat);

    tm1 = darshan_core_wtime();
    ret = __real___fxstat(vers, fd, buf);
    tm2 = darshan_core_wtime();

    if(ret < 0 || !S_ISREG(buf->st_mode))
        return(ret);

876
    POSIX_PRE_RECORD();
877 878
    rec_ref = darshan_lookup_record_ref(posix_runtime->fd_hash, &fd, sizeof(int));
    if(rec_ref)
879
    {
880
        POSIX_RECORD_STAT(rec_ref, buf, tm1, tm2);
881
    }
882
    POSIX_POST_RECORD();
883 884 885 886 887 888 889

    return(ret);
}

int DARSHAN_DECL(__fxstat64)(int vers, int fd, struct stat64 *buf)
{
    int ret;
890
    struct posix_file_record_ref *rec_ref;
891 892 893 894 895 896 897 898 899 900 901
    double tm1, tm2;

    MAP_OR_FAIL(__fxstat64);

    tm1 = darshan_core_wtime();
    ret = __real___fxstat64(vers, fd, buf);
    tm2 = darshan_core_wtime();

    if(ret < 0 || !S_ISREG(buf->st_mode))
        return(ret);

902
    POSIX_PRE_RECORD();
903 904
    rec_ref = darshan_lookup_record_ref(posix_runtime->fd_hash, &fd, sizeof(int));
    if(rec_ref)
905
    {
906
        POSIX_RECORD_STAT(rec_ref, buf, tm1, tm2);
907
    }
908
    POSIX_POST_RECORD();
909 910 911 912

    return(ret);
}

Shane Snyder's avatar
Shane Snyder committed
913 914 915 916
void* DARSHAN_DECL(mmap)(void *addr, size_t length, int prot, int flags,
    int fd, off_t offset)
{
    void* ret;
917
    struct posix_file_record_ref *rec_ref;
Shane Snyder's avatar
Shane Snyder committed
918 919 920 921 922 923 924

    MAP_OR_FAIL(mmap);

    ret = __real_mmap(addr, length, prot, flags, fd, offset);
    if(ret == MAP_FAILED)
        return(ret);

925
    POSIX_PRE_RECORD();
926 927
    rec_ref = darshan_lookup_record_ref(posix_runtime->fd_hash, &fd, sizeof(int));
    if(rec_ref)
Shane Snyder's avatar
Shane Snyder committed
928
    {
929
        rec_ref->file_rec->counters[POSIX_MMAPS] += 1;
Shane Snyder's avatar
Shane Snyder committed
930
    }
931
    POSIX_POST_RECORD();
Shane Snyder's avatar
Shane Snyder committed
932 933 934 935 936 937 938 939

    return(ret);
}

void* DARSHAN_DECL(mmap64)(void *addr, size_t length, int prot, int flags,
    int fd, off64_t offset)
{
    void* ret;
940
    struct posix_file_record_ref *rec_ref;
Shane Snyder's avatar
Shane Snyder committed
941 942 943 944 945 946 947

    MAP_OR_FAIL(mmap64);

    ret = __real_mmap64(addr, length, prot, flags, fd, offset);
    if(ret == MAP_FAILED)
        return(ret);

948
    POSIX_PRE_RECORD();
949 950
    rec_ref = darshan_lookup_record_ref(posix_runtime->fd_hash, &fd, sizeof(int));
    if(rec_ref)
Shane Snyder's avatar
Shane Snyder committed
951
    {
952
        rec_ref->file_rec->counters[POSIX_MMAPS] += 1;
Shane Snyder's avatar
Shane Snyder committed
953
    }
954
    POSIX_POST_RECORD();
Shane Snyder's avatar
Shane Snyder committed
955 956 957 958

    return(ret);
}

959 960 961
int DARSHAN_DECL(fsync)(int fd)
{
    int ret;
962
    struct posix_file_record_ref *rec_ref;
963 964 965 966 967 968 969 970 971 972 973
    double tm1, tm2;

    MAP_OR_FAIL(fsync);

    tm1 = darshan_core_wtime();
    ret = __real_fsync(fd);
    tm2 = darshan_core_wtime();

    if(ret < 0)
        return(ret);

974
    POSIX_PRE_RECORD();
975 976
    rec_ref = darshan_lookup_record_ref(posix_runtime->fd_hash, &fd, sizeof(int));
    if(rec_ref)
977
    {
978
        DARSHAN_TIMER_INC_NO_OVERLAP(
979 980 981
            rec_ref->file_rec->fcounters[POSIX_F_WRITE_TIME],
            tm1, tm2, rec_ref->last_write_end);
        rec_ref->file_rec->counters[POSIX_FSYNCS] += 1;
982
    }
983
    POSIX_POST_RECORD();
984 985 986 987 988 989 990

    return(ret);
}

int DARSHAN_DECL(fdatasync)(int fd)
{
    int ret;
991
    struct posix_file_record_ref *rec_ref;
992 993 994 995 996 997 998 999 1000 1001 1002
    double tm1, tm2;

    MAP_OR_FAIL(fdatasync);

    tm1 = darshan_core_wtime();
    ret = __real_fdatasync(fd);
    tm2 = darshan_core_wtime();

    if(ret < 0)
        return(ret);

1003
    POSIX_PRE_RECORD();
1004 1005
    rec_ref = darshan_lookup_record_ref(posix_runtime->fd_hash, &fd, sizeof(int));
    if(rec_ref)
1006
    {
1007
        DARSHAN_TIMER_INC_NO_OVERLAP(
1008 1009 1010
            rec_ref->file_rec->fcounters[POSIX_F_WRITE_TIME],
            tm1, tm2, rec_ref->last_write_end);
        rec_ref->file_rec->counters[POSIX_FDSYNCS] += 1;
1011
    }
1012
    POSIX_POST_RECORD();
1013 1014 1015 1016

    return(ret);
}

1017 1018 1019
int DARSHAN_DECL(close)(int fd)
{
    int ret;
1020 1021
    struct posix_file_record_ref *rec_ref;
    double tm1, tm2;
1022 1023 1024 1025 1026 1027 1028

    MAP_OR_FAIL(close);

    tm1 = darshan_core_wtime();
    ret = __real_close(fd);
    tm2 = darshan_core_wtime();

1029
    POSIX_PRE_RECORD();
1030 1031
    rec_ref = darshan_lookup_record_ref(posix_runtime->fd_hash, &fd, sizeof(int));
    if(rec_ref)
Shane Snyder's avatar
Shane Snyder committed
1032
    {
1033 1034 1035
        rec_ref->last_byte_written = 0;
        rec_ref->last_byte_read = 0;
        rec_ref->file_rec->fcounters[POSIX_F_CLOSE_TIMESTAMP] =
1036 1037
            darshan_core_wtime();
        DARSHAN_TIMER_INC_NO_OVERLAP(
1038 1039 1040
            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));
Shane Snyder's avatar
Shane Snyder committed
1041
    }
1042
    POSIX_POST_RECORD();
1043 1044 1045 1046

    return(ret);
}

1047 1048 1049 1050 1051 1052 1053 1054 1055
int DARSHAN_DECL(aio_read)(struct aiocb *aiocbp)
{
    int ret;

    MAP_OR_FAIL(aio_read);

    ret = __real_aio_read(aiocbp);
    if(ret == 0)
    {
1056
        POSIX_PRE_RECORD();
1057
        posix_aio_tracker_add(aiocbp->aio_fildes, aiocbp);
1058
        POSIX_POST_RECORD();
1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072
    }

    return(ret);
}

int DARSHAN_DECL(aio_write)(struct aiocb *aiocbp)
{
    int ret;

    MAP_OR_FAIL(aio_write);

    ret = __real_aio_write(aiocbp);
    if(ret == 0)
    {
1073
        POSIX_PRE_RECORD();
1074
        posix_aio_tracker_add(aiocbp->aio_fildes, aiocbp);
1075
        POSIX_POST_RECORD();
1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089
    }

    return(ret);
}

int DARSHAN_DECL(aio_read64)(struct aiocb64 *aiocbp)
{
    int ret;

    MAP_OR_FAIL(aio_read64);

    ret = __real_aio_read64(aiocbp);
    if(ret == 0)
    {
1090
        POSIX_PRE_RECORD();
1091
        posix_aio_tracker_add(aiocbp->aio_fildes, aiocbp);
1092
        POSIX_POST_RECORD();
1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106
    }

    return(ret);
}

int DARSHAN_DECL(aio_write64)(struct aiocb64 *aiocbp)
{
    int ret;

    MAP_OR_FAIL(aio_write64);

    ret = __real_aio_write64(aiocbp);
    if(ret == 0)
    {
1107
        POSIX_PRE_RECORD();
1108
        posix_aio_tracker_add(aiocbp->aio_fildes, aiocbp);
1109
        POSIX_POST_RECORD();
1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126
    }

    return(ret);
}

ssize_t DARSHAN_DECL(aio_return)(struct aiocb *aiocbp)
{
    int ret;
    double tm2;
    struct posix_aio_tracker *tmp;
    int aligned_flag = 0;

    MAP_OR_FAIL(aio_return);

    ret = __real_aio_return(aiocbp);
    tm2 = darshan_core_wtime();

1127
    POSIX_PRE_RECORD();
1128
    tmp = posix_aio_tracker_del(aiocbp->aio_fildes, aiocbp);
1129
    if(tmp)
1130 1131 1132 1133 1134 1135
    {
        if((unsigned long)aiocbp->aio_buf % darshan_mem_alignment == 0)
            aligned_flag = 1;
        if(aiocbp->aio_lio_opcode == LIO_WRITE)
        {
            POSIX_RECORD_WRITE(ret, aiocbp->aio_fildes,
Philip Carns's avatar
Philip Carns committed
1136
                1, aiocbp->aio_offset, aligned_flag,
1137 1138 1139 1140 1141
                tmp->tm1, tm2);
        }
        else if(aiocbp->aio_lio_opcode == LIO_READ)
        {
            POSIX_RECORD_READ(ret, aiocbp->aio_fildes,
Philip Carns's avatar
Philip Carns committed
1142
                1, aiocbp->aio_offset, aligned_flag,
1143 1144 1145 1146
                tmp->tm1, tm2);
        }
        free(tmp);
    }
1147
    POSIX_POST_RECORD();
1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163

    return(ret);
}

ssize_t DARSHAN_DECL(aio_return64)(struct aiocb64 *aiocbp)
{
    int ret;
    double tm2;
    struct posix_aio_tracker *tmp;
    int aligned_flag = 0;

    MAP_OR_FAIL(aio_return64);

    ret = __real_aio_return64(aiocbp);
    tm2 = darshan_core_wtime();

1164
    POSIX_PRE_RECORD();
1165
    tmp = posix_aio_tracker_del(aiocbp->aio_fildes, aiocbp);
1166
    if(tmp)
1167 1168 1169 1170 1171 1172
    {
        if((unsigned long)aiocbp->aio_buf % darshan_mem_alignment == 0)
            aligned_flag = 1;
        if(aiocbp->aio_lio_opcode == LIO_WRITE)
        {
            POSIX_RECORD_WRITE(ret, aiocbp->aio_fildes,
Philip Carns's avatar
Philip Carns committed
1173
                1, aiocbp->aio_offset, aligned_flag,
1174 1175 1176 1177 1178
                tmp->tm1, tm2);
        }
        else if(aiocbp->aio_lio_opcode == LIO_READ)
        {
            POSIX_RECORD_READ(ret, aiocbp->aio_fildes,
Philip Carns's avatar
Philip Carns committed
1179
                1, aiocbp->aio_offset, aligned_flag,
1180 1181 1182 1183
                tmp->tm1, tm2);
        }
        free(tmp);
    }
1184
    POSIX_POST_RECORD();
1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199

    return(ret);
}

int DARSHAN_DECL(lio_listio)(int mode, struct aiocb *const aiocb_list[],
    int nitems, struct sigevent *sevp)
{
    int ret;
    int i;

    MAP_OR_FAIL(lio_listio);

    ret = __real_lio_listio(mode, aiocb_list, nitems, sevp);
    if(ret == 0)
    {
1200
        POSIX_PRE_RECORD();
1201 1202 1203 1204
        for(i = 0; i < nitems; i++)
        {
            posix_aio_tracker_add(aiocb_list[i]->aio_fildes, aiocb_list[i]);
        }
1205
        POSIX_POST_RECORD();
1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221
    }

    return(ret);
}

int DARSHAN_DECL(lio_listio64)(int mode, struct aiocb64 *const aiocb_list[],
    int nitems, struct sigevent *sevp)
{
    int ret;
    int i;

    MAP_OR_FAIL(lio_listio64);

    ret = __real_lio_listio64(mode, aiocb_list, nitems, sevp);
    if(ret == 0)
    {
1222
        POSIX_PRE_RECORD();
1223 1224 1225 1226
        for(i = 0; i < nitems; i++)
        {
            posix_aio_tracker_add(aiocb_list[i]->aio_fildes, aiocb_list[i]);
        }
1227
        POSIX_POST_RECORD();
1228 1229 1230 1231 1232
    }

    return(ret);
}

1233 1234 1235
/**********************************************************
 * Internal functions for manipulating POSIX module state *
 **********************************************************/
1236

1237
/* initialize internal POSIX module data structures and register with darshan-core */
1238
static void posix_runtime_initialize()
1239
{
1240
    int psx_buf_size;
1241

1242
    /* try and store a default number of records for this module */
1243 1244
    psx_buf_size = DARSHAN_DEF_MOD_REC_COUNT * sizeof(struct darshan_posix_file);

1245
    /* register the POSIX module with darshan core */
1246
    darshan_core_register_module(
1247
        DARSHAN_POSIX_MOD,
1248
        &posix_shutdown,
1249
        &psx_buf_size,
1250
        &my_rank,
1251
        &darshan_mem_alignment);
1252

1253 1254
    /* return if darshan-core does not provide enough module memory */
    if(psx_buf_size < sizeof(struct darshan_posix_file))
1255 1256
    {
        darshan_core_unregister_module(DARSHAN_POSIX_MOD);
1257
        return;
1258
    }
1259 1260 1261

    posix_runtime = malloc(sizeof(*posix_runtime));
    if(!posix_runtime)
1262 1263
    {
        darshan_core_unregister_module(DARSHAN_POSIX_MOD);
1264
        return;