darshan-posix.c 62.1 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 42 43
#ifndef LL_SUPER_MAGIC
#define LL_SUPER_MAGIC 0x0BD00BD0
#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
DARSHAN_FORWARD_DECL(fopen, FILE*, (const char *path, const char *mode));
DARSHAN_FORWARD_DECL(fopen64, FILE*, (const char *path, const char *mode));
50 51 52 53
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));
54 55 56 57 58 59 60 61
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));
62 63 64 65 66
DARSHAN_FORWARD_DECL(fread, size_t, (void *ptr, size_t size, size_t nmemb, FILE *stream));
DARSHAN_FORWARD_DECL(fwrite, size_t, (const void *ptr, size_t size, size_t nmemb, FILE *stream));
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));
DARSHAN_FORWARD_DECL(fseek, int, (FILE *stream, long offset, int whence));
67 68 69 70 71 72
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
73 74
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));
75 76
DARSHAN_FORWARD_DECL(fsync, int, (int fd));
DARSHAN_FORWARD_DECL(fdatasync, int, (int fd));
77
DARSHAN_FORWARD_DECL(close, int, (int fd));
78
DARSHAN_FORWARD_DECL(fclose, int, (FILE *fp));
79 80 81 82 83 84 85 86
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));
87

88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
/* 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)
106 107
 * 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,
108 109
 * there could be multiple open file descriptors that index it.
 */
110
struct posix_file_record_ref
111
{
112
    struct darshan_posix_file *file_rec;
113 114 115
    int64_t offset;
    int64_t last_byte_read;
    int64_t last_byte_written;
Shane Snyder's avatar
Shane Snyder committed
116
    enum darshan_io_type last_io_type;
117 118 119
    double last_meta_end;
    double last_read_end;
    double last_write_end;
120
    void *access_root;
121
    int access_count;
122
    void *stride_root;
123
    int stride_count;
124
    struct posix_aio_tracker* aio_list;
125 126
};

127 128 129 130
/* The posix_runtime structure maintains necessary state for storing
 * POSIX file records and for coordinating with darshan-core at 
 * shutdown time.
 */
131 132
struct posix_runtime
{
133 134 135
    void *rec_id_hash;
    void *fd_hash;
    int file_rec_count;
136 137
};

138 139 140 141 142
/* struct to track information about aio operations in flight */
struct posix_aio_tracker
{
    double tm1;
    void *aiocbp;
143
    struct posix_aio_tracker *next;
144
};
145

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

static void posix_shutdown(
165
    MPI_Comm mod_comm, darshan_record_id *shared_recs,
166
    int shared_rec_count, void **posix_buf, int *posix_buf_sz);
167

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

175 176 177 178 179 180
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;

181 182 183
#define POSIX_LOCK() pthread_mutex_lock(&posix_runtime_mutex)
#define POSIX_UNLOCK() pthread_mutex_unlock(&posix_runtime_mutex)

184 185 186 187 188 189 190 191 192 193 194 195
#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)
196

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

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

290 291
#define POSIX_RECORD_WRITE(__ret, __fd, __pwrite_flag, __pwrite_offset, __aligned, __stream_flag, __tm1, __tm2) do { \
    struct posix_file_record_ref* rec_ref; \
292
    size_t stride; \
293
    int64_t this_offset; \
294
    int64_t file_alignment; \
295 296
    double __elapsed = __tm2-__tm1; \
    if(__ret < 0) break; \
297 298
    rec_ref = darshan_lookup_record_ref(posix_runtime->fd_hash, &__fd, sizeof(int)); \
    if(!rec_ref) break; \
299
    if(__pwrite_flag) \
300 301
        this_offset = __pwrite_offset; \
    else \
302 303 304 305 306 307 308 309
        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; \
310
    else \
311
        stride = 0; \
312 313 314 315 316
    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; \
317
    if(__stream_flag) \
318
        rec_ref->file_rec->counters[POSIX_FWRITES] += 1; \
319
    else \
320 321 322 323 324 325 326 327
        rec_ref->file_rec->counters[POSIX_WRITES] += 1; \
    DARSHAN_BUCKET_INC(&(rec_ref->file_rec->counters[POSIX_SIZE_WRITE_0_100]), __ret); \
    darshan_common_val_counter(&rec_ref->access_root, &rec_ref->access_count, __ret, \
        &(rec_ref->file_rec->counters[POSIX_ACCESS1_ACCESS]), \
        &(rec_ref->file_rec->counters[POSIX_ACCESS1_COUNT])); \
    darshan_common_val_counter(&rec_ref->stride_root, &rec_ref->stride_count, stride, \
        &(rec_ref->file_rec->counters[POSIX_STRIDE1_STRIDE]), \
        &(rec_ref->file_rec->counters[POSIX_STRIDE1_COUNT])); \
328
    if(!__aligned) \
329 330
        rec_ref->file_rec->counters[POSIX_MEM_NOT_ALIGNED] += 1; \
    file_alignment = rec_ref->file_rec->counters[POSIX_FILE_ALIGNMENT]; \
331
    if(file_alignment > 0 && (this_offset % file_alignment) != 0) \
332 333 334 335
        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; \
336 337
    if(rec_ref->file_rec->fcounters[POSIX_F_WRITE_START_TIMESTAMP] == 0 || \
     rec_ref->file_rec->fcounters[POSIX_F_WRITE_START_TIMESTAMP] > __tm1) \
338 339 340 341 342 343 344
        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); \
345
} while(0)
346

347
#define POSIX_LOOKUP_RECORD_STAT(__path, __statbuf, __tm1, __tm2) do { \
348
    darshan_record_id rec_id; \
349 350 351 352 353 354
    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; \
355
    } \
356 357
    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)); \
358
    if(!rec_ref) rec_ref = posix_track_new_file_record(rec_id, newpath, -1); \
359
    if(newpath != __path) free(newpath); \
360 361
    if(rec_ref) { \
        POSIX_RECORD_STAT(rec_ref, __statbuf, __tm1, __tm2); \
362 363 364
    } \
} while(0)

365 366 367 368
#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); \
369 370
} while(0)

371

372 373 374 375
/**********************************************************
 *      Wrappers for POSIX I/O functions of interest      * 
 **********************************************************/

376
int DARSHAN_DECL(open)(const char *path, int flags, ...)
377 378 379 380 381
{
    int mode = 0;
    int ret;
    double tm1, tm2;

382 383
    MAP_OR_FAIL(open);

384
    if(flags & O_CREAT) 
385 386 387 388 389 390
    {
        va_list arg;
        va_start(arg, flags);
        mode = va_arg(arg, int);
        va_end(arg);

391
        tm1 = darshan_core_wtime();
392
        ret = __real_open(path, flags, mode);
393
        tm2 = darshan_core_wtime();
394 395 396
    }
    else
    {
397
        tm1 = darshan_core_wtime();
398
        ret = __real_open(path, flags);
399
        tm2 = darshan_core_wtime();
400 401
    }

402
    POSIX_PRE_RECORD();
403
    POSIX_RECORD_OPEN(ret, path, mode, 0, tm1, tm2);
404
    POSIX_POST_RECORD();
405 406 407 408

    return(ret);
}

Shane Snyder's avatar
Shane Snyder committed
409 410 411 412 413 414
int DARSHAN_DECL(open64)(const char *path, int flags, ...)
{
    int mode = 0;
    int ret;
    double tm1, tm2;

415
    MAP_OR_FAIL(open64);
Shane Snyder's avatar
Shane Snyder committed
416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434

    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();
    }

435
    POSIX_PRE_RECORD();
436
    POSIX_RECORD_OPEN(ret, path, mode, 0, tm1, tm2);
437
    POSIX_POST_RECORD();
438 439 440 441 442 443 444 445 446 447 448 449 450 451 452

    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();

453
    POSIX_PRE_RECORD();
454
    POSIX_RECORD_OPEN(ret, path, mode, 0, tm1, tm2);
455
    POSIX_POST_RECORD();
456 457 458 459 460 461 462 463 464 465

    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
466

467 468 469 470
    tm1 = darshan_core_wtime();
    ret = __real_creat64(path, mode);
    tm2 = darshan_core_wtime();

471
    POSIX_PRE_RECORD();
Shane Snyder's avatar
Shane Snyder committed
472
    POSIX_RECORD_OPEN(ret, path, mode, 0, tm1, tm2);
473
    POSIX_POST_RECORD();
Shane Snyder's avatar
Shane Snyder committed
474 475 476 477

    return(ret);
}

478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494
FILE* DARSHAN_DECL(fopen)(const char *path, const char *mode)
{
    FILE* ret;
    int fd;
    double tm1, tm2;

    MAP_OR_FAIL(fopen);

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

    if(ret == NULL)
        fd = -1;
    else
        fd = fileno(ret);

495
    POSIX_PRE_RECORD();
496
    POSIX_RECORD_OPEN(fd, path, 0, 1, tm1, tm2);
497
    POSIX_POST_RECORD();
498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518

    return(ret);
}

FILE* DARSHAN_DECL(fopen64)(const char *path, const char *mode)
{
    FILE* ret;
    int fd;
    double tm1, tm2;

    MAP_OR_FAIL(fopen64);

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

    if(ret == NULL)
        fd = -1;
    else
        fd = fileno(ret);

519
    POSIX_PRE_RECORD();
520
    POSIX_RECORD_OPEN(fd, path, 0, 1, tm1, tm2);
521
    POSIX_POST_RECORD();
522 523 524 525

    return(ret);
}

526 527 528 529 530 531 532 533 534 535 536
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();

537
    POSIX_PRE_RECORD();
538
    POSIX_RECORD_OPEN(ret, template, 0, 0, tm1, tm2);
539
    POSIX_POST_RECORD();
540 541 542 543 544 545 546 547 548 549 550 551 552 553 554

    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();

555
    POSIX_PRE_RECORD();
556
    POSIX_RECORD_OPEN(ret, template, 0, 0, tm1, tm2);
557
    POSIX_POST_RECORD();
558 559 560 561 562 563 564 565 566 567 568 569 570 571 572

    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();

573
    POSIX_PRE_RECORD();
574
    POSIX_RECORD_OPEN(ret, template, 0, 0, tm1, tm2);
575
    POSIX_POST_RECORD();
576 577 578 579 580 581 582 583 584 585 586 587 588 589 590

    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();

591
    POSIX_PRE_RECORD();
592
    POSIX_RECORD_OPEN(ret, template, 0, 0, tm1, tm2);
593
    POSIX_POST_RECORD();
594 595 596 597

    return(ret);
}

598 599 600 601 602 603
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
604
    MAP_OR_FAIL(read);
605

606
    if((unsigned long)buf % darshan_mem_alignment == 0) aligned_flag = 1;
607 608 609 610 611

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

612
    POSIX_PRE_RECORD();
613
    POSIX_RECORD_READ(ret, fd, 0, 0, aligned_flag, 0, tm1, tm2);
614
    POSIX_POST_RECORD();
615 616 617 618 619 620 621 622 623 624 625 626

    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);

627
    if((unsigned long)buf % darshan_mem_alignment == 0) aligned_flag = 1;
628 629 630 631 632

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

633
    POSIX_PRE_RECORD();
634
    POSIX_RECORD_WRITE(ret, fd, 0, 0, aligned_flag, 0, tm1, tm2);
635
    POSIX_POST_RECORD();
636 637 638 639 640 641 642 643 644 645 646 647

    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);

648
    if((unsigned long)buf % darshan_mem_alignment == 0) aligned_flag = 1;
649 650 651 652 653

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

654
    POSIX_PRE_RECORD();
655
    POSIX_RECORD_READ(ret, fd, 1, offset, aligned_flag, 0, tm1, tm2);
656
    POSIX_POST_RECORD();
657 658 659 660 661 662 663 664 665 666 667 668

    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);

669
    if((unsigned long)buf % darshan_mem_alignment == 0) aligned_flag = 1;
670 671 672 673 674

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

675
    POSIX_PRE_RECORD();
676
    POSIX_RECORD_WRITE(ret, fd, 1, offset, aligned_flag, 0, tm1, tm2);
677
    POSIX_POST_RECORD();
678 679 680 681 682 683 684 685 686 687 688 689

    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);

690
    if((unsigned long)buf % darshan_mem_alignment == 0) aligned_flag = 1;
691 692 693 694 695

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

696
    POSIX_PRE_RECORD();
697
    POSIX_RECORD_READ(ret, fd, 1, offset, aligned_flag, 0, tm1, tm2);
698
    POSIX_POST_RECORD();
699 700 701 702 703 704 705 706 707 708 709 710

    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);

711
    if((unsigned long)buf % darshan_mem_alignment == 0) aligned_flag = 1;
712 713 714 715 716

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

717
    POSIX_PRE_RECORD();
718
    POSIX_RECORD_WRITE(ret, fd, 1, offset, aligned_flag, 0, tm1, tm2);
719
    POSIX_POST_RECORD();
720 721 722 723 724 725 726

    return(ret);
}

ssize_t DARSHAN_DECL(readv)(int fd, const struct iovec *iov, int iovcnt)
{
    ssize_t ret;
727
    int aligned_flag = 1;
728 729 730 731
    int i;
    double tm1, tm2;

    MAP_OR_FAIL(readv);
732

733 734 735 736
    for(i=0; i<iovcnt; i++)
    {
        if(((unsigned long)iov[i].iov_base % darshan_mem_alignment) != 0)
            aligned_flag = 0;
737
    }
738 739 740 741 742

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

743
    POSIX_PRE_RECORD();
744
    POSIX_RECORD_READ(ret, fd, 0, 0, aligned_flag, 0, tm1, tm2);
745
    POSIX_POST_RECORD();
746 747 748 749 750 751 752

    return(ret);
}

ssize_t DARSHAN_DECL(writev)(int fd, const struct iovec *iov, int iovcnt)
{
    ssize_t ret;
753
    int aligned_flag = 1;
754 755 756 757
    int i;
    double tm1, tm2;

    MAP_OR_FAIL(writev);
758

759 760 761 762
    for(i=0; i<iovcnt; i++)
    {
        if(((unsigned long)iov[i].iov_base % darshan_mem_alignment) != 0)
            aligned_flag = 0;
763
    }
764 765 766 767 768

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

769
    POSIX_PRE_RECORD();
770
    POSIX_RECORD_WRITE(ret, fd, 0, 0, aligned_flag, 0, tm1, tm2);
771
    POSIX_POST_RECORD();
772 773 774 775

    return(ret);
}

776 777 778 779
size_t DARSHAN_DECL(fread)(void *ptr, size_t size, size_t nmemb, FILE *stream)
{
    size_t ret;
    int aligned_flag = 0;
780
    int fd;
781 782 783 784
    double tm1, tm2;

    MAP_OR_FAIL(fread);

785
    if((unsigned long)ptr % darshan_mem_alignment == 0) aligned_flag = 1;
786 787 788 789 790

    tm1 = darshan_core_wtime();
    ret = __real_fread(ptr, size, nmemb, stream);
    tm2 = darshan_core_wtime();

791
    fd = fileno(stream);
792
    POSIX_PRE_RECORD();
793 794
    if(ret > 0)
    {
795
        POSIX_RECORD_READ(size*ret, fd, 0, 0, aligned_flag, 1, tm1, tm2);
796 797 798
    }
    else
    {
799
        POSIX_RECORD_READ(ret, fd, 0, 0, aligned_flag, 1, tm1, tm2);
800
    }
801
    POSIX_POST_RECORD();
802 803 804 805 806 807 808 809

    return(ret);
}

size_t DARSHAN_DECL(fwrite)(const void *ptr, size_t size, size_t nmemb, FILE *stream)
{
    size_t ret;
    int aligned_flag = 0;
810
    int fd;
811 812 813 814
    double tm1, tm2;

    MAP_OR_FAIL(fwrite);

815
    if((unsigned long)ptr % darshan_mem_alignment == 0) aligned_flag = 1;
816 817 818 819 820

    tm1 = darshan_core_wtime();
    ret = __real_fwrite(ptr, size, nmemb, stream);
    tm2 = darshan_core_wtime();

821
    fd = fileno(stream);
822
    POSIX_PRE_RECORD();
823 824
    if(ret > 0)
    {
825
        POSIX_RECORD_WRITE(size*ret, fd, 0, 0, aligned_flag, 1, tm1, tm2);
826 827 828
    }
    else
    {
829
        POSIX_RECORD_WRITE(ret, fd, 0, 0, aligned_flag, 1, tm1, tm2);
830
    }
831
    POSIX_POST_RECORD();
832 833 834 835 836 837 838

    return(ret);
}

off_t DARSHAN_DECL(lseek)(int fd, off_t offset, int whence)
{
    off_t ret;
839
    struct posix_file_record_ref *rec_ref;
840 841 842 843 844 845 846 847 848 849
    double tm1, tm2;

    MAP_OR_FAIL(lseek);

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

    if(ret >= 0)
    {
850
        POSIX_PRE_RECORD();
851 852
        rec_ref = darshan_lookup_record_ref(posix_runtime->fd_hash, &fd, sizeof(int));
        if(rec_ref)
853
        {
854
            rec_ref->offset = ret;
855
            DARSHAN_TIMER_INC_NO_OVERLAP(
856 857 858
                rec_ref->file_rec->fcounters[POSIX_F_META_TIME],
                tm1, tm2, rec_ref->last_meta_end);
            rec_ref->file_rec->counters[POSIX_SEEKS] += 1;
859
        }
860
        POSIX_POST_RECORD();
861 862 863 864 865 866 867 868
    }

    return(ret);
}

off_t DARSHAN_DECL(lseek64)(int fd, off_t offset, int whence)
{
    off_t ret;
869
    struct posix_file_record_ref *rec_ref;
870 871 872 873 874 875 876 877 878 879
    double tm1, tm2;

    MAP_OR_FAIL(lseek64);

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

    if(ret >= 0)
    {
880
        POSIX_PRE_RECORD();
881 882
        rec_ref = darshan_lookup_record_ref(posix_runtime->fd_hash, &fd, sizeof(int));
        if(rec_ref)
883
        {
884
            rec_ref->offset = ret;
885
            DARSHAN_TIMER_INC_NO_OVERLAP(
886 887 888
                rec_ref->file_rec->fcounters[POSIX_F_META_TIME],
                tm1, tm2, rec_ref->last_meta_end);
            rec_ref->file_rec->counters[POSIX_SEEKS] += 1;
889
        }
890
        POSIX_POST_RECORD();
891 892 893 894 895 896 897 898
    }

    return(ret);
}

int DARSHAN_DECL(fseek)(FILE *stream, long offset, int whence)
{
    int ret;
899 900
    struct posix_file_record_ref *rec_ref;
    int fd;
901 902 903 904 905 906 907 908 909 910
    double tm1, tm2;

    MAP_OR_FAIL(fseek);

    tm1 = darshan_core_wtime();
    ret = __real_fseek(stream, offset, whence);
    tm2 = darshan_core_wtime();

    if(ret >= 0)
    {
911
        POSIX_PRE_RECORD();
912 913 914
        fd = fileno(stream);
        rec_ref = darshan_lookup_record_ref(posix_runtime->fd_hash, &fd, sizeof(int));
        if(rec_ref)
915
        {
916
            rec_ref->offset = ftell(stream);
917
            DARSHAN_TIMER_INC_NO_OVERLAP(
918 919 920
                rec_ref->file_rec->fcounters[POSIX_F_META_TIME],
                tm1, tm2, rec_ref->last_meta_end);
            rec_ref->file_rec->counters[POSIX_FSEEKS] += 1;
921
        }
922
        POSIX_POST_RECORD();
923 924 925 926 927
    }

    return(ret);
}

928 929 930 931 932 933 934 935 936 937 938 939 940 941
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);

942
    POSIX_PRE_RECORD();
943
    POSIX_LOOKUP_RECORD_STAT(path, buf, tm1, tm2);
944
    POSIX_POST_RECORD();
945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962

    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);

963
    POSIX_PRE_RECORD();
964
    POSIX_LOOKUP_RECORD_STAT(path, buf, tm1, tm2);
965
    POSIX_POST_RECORD();
966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983

    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);

984
    POSIX_PRE_RECORD();
985
    POSIX_LOOKUP_RECORD_STAT(path, buf, tm1, tm2);
986
    POSIX_POST_RECORD();
987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004

    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);

1005
    POSIX_PRE_RECORD();
1006
    POSIX_LOOKUP_RECORD_STAT(path, buf, tm1, tm2);
1007
    POSIX_POST_RECORD();
1008 1009 1010 1011 1012 1013 1014

    return(ret);
}

int DARSHAN_DECL(__fxstat)(int vers, int fd, struct stat *buf)
{
    int ret;
1015
    struct posix_file_record_ref *rec_ref;
1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026
    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);

1027
    POSIX_PRE_RECORD();
1028 1029
    rec_ref = darshan_lookup_record_ref(posix_runtime->fd_hash, &fd, sizeof(int));
    if(rec_ref)
1030
    {
1031
        POSIX_RECORD_STAT(rec_ref, buf, tm1, tm2);
1032
    }
1033
    POSIX_POST_RECORD();
1034 1035 1036 1037 1038 1039 1040

    return(ret);
}

int DARSHAN_DECL(__fxstat64)(int vers, int fd, struct stat64 *buf)
{
    int ret;
1041
    struct posix_file_record_ref *rec_ref;
1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052
    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);

1053
    POSIX_PRE_RECORD();
1054 1055
    rec_ref = darshan_lookup_record_ref(posix_runtime->fd_hash, &fd, sizeof(int));
    if(rec_ref)
1056
    {
1057
        POSIX_RECORD_STAT(rec_ref, buf, tm1, tm2);
1058
    }
1059
    POSIX_POST_RECORD();
1060 1061 1062 1063

    return(ret);
}

Shane Snyder's avatar
Shane Snyder committed
1064 1065 1066 1067
void* DARSHAN_DECL(mmap)(void *addr, size_t length, int prot, int flags,
    int fd, off_t offset)
{
    void* ret;
1068
    struct posix_file_record_ref *rec_ref;
Shane Snyder's avatar
Shane Snyder committed
1069 1070 1071 1072 1073 1074 1075

    MAP_OR_FAIL(mmap);

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

1076
    POSIX_PRE_RECORD();
1077 1078
    rec_ref = darshan_lookup_record_ref(posix_runtime->fd_hash, &fd, sizeof(int));
    if(rec_ref)
Shane Snyder's avatar
Shane Snyder committed
1079
    {
1080
        rec_ref->file_rec->counters[POSIX_MMAPS] += 1;
Shane Snyder's avatar
Shane Snyder committed
1081
    }
1082
    POSIX_POST_RECORD();
Shane Snyder's avatar
Shane Snyder committed
1083 1084 1085 1086 1087 1088 1089 1090

    return(ret);
}

void* DARSHAN_DECL(mmap64)(void *addr, size_t length, int prot, int flags,
    int fd, off64_t offset)
{
    void* ret;
1091
    struct posix_file_record_ref *rec_ref;
Shane Snyder's avatar
Shane Snyder committed
1092 1093 1094 1095 1096 1097 1098

    MAP_OR_FAIL(mmap64);

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

1099
    POSIX_PRE_RECORD();
1100 1101
    rec_ref = darshan_lookup_record_ref(posix_runtime->fd_hash, &fd, sizeof(int));
    if(rec_ref)
Shane Snyder's avatar
Shane Snyder committed
1102
    {
1103
        rec_ref->file_rec->counters[POSIX_MMAPS] += 1;
Shane Snyder's avatar
Shane Snyder committed
1104
    }
1105
    POSIX_POST_RECORD();
Shane Snyder's avatar
Shane Snyder committed
1106 1107 1108 1109

    return(ret);
}

1110 1111 1112
int DARSHAN_DECL(fsync)(int fd)
{
    int ret;
1113
    struct posix_file_record_ref *rec_ref;
1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124
    double tm1, tm2;

    MAP_OR_FAIL(fsync);

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

    if(ret < 0)
        return(ret);

1125
    POSIX_PRE_RECORD();
1126 1127
    rec_ref = darshan_lookup_record_ref(posix_runtime->fd_hash, &fd, sizeof(int));
    if(rec_ref)
1128
    {
1129
        DARSHAN_TIMER_INC_NO_OVERLAP(
1130 1131 1132
            rec_ref->file_rec->fcounters[POSIX_F_WRITE_TIME],
            tm1, tm2, rec_ref->last_write_end);
        rec_ref->file_rec->counters[POSIX_FSYNCS] += 1;
1133
    }
1134
    POSIX_POST_RECORD();
1135 1136 1137 1138 1139 1140 1141

    return(ret);
}

int DARSHAN_DECL(fdatasync)(int fd)
{
    int ret;
1142
    struct posix_file_record_ref *rec_ref;
1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153
    double tm1, tm2;

    MAP_OR_FAIL(fdatasync);

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

    if(ret < 0)
        return(ret);

1154
    POSIX_PRE_RECORD();
1155 1156
    rec_ref = darshan_lookup_record_ref(posix_runtime->fd_hash, &fd, sizeof(int));
    if(rec_ref)
1157
    {
1158
        DARSHAN_TIMER_INC_NO_OVERLAP(
1159 1160 1161
            rec_ref->file_rec->fcounters[POSIX_F_WRITE_TIME],
            tm1, tm2, rec_ref->last_write_end);
        rec_ref->file_rec->counters[POSIX_FDSYNCS] += 1;
1162
    }
1163
    POSIX_POST_RECORD();
1164 1165 1166 1167

    return(ret);
}

1168 1169 1170
int DARSHAN_DECL(close)(int fd)
{
    int ret;
1171 1172
    struct posix_file_record_ref *rec_ref;
    double tm1, tm2;
1173 1174 1175 1176 1177 1178 1179

    MAP_OR_FAIL(close);

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

1180
    POSIX_PRE_RECORD();
1181 1182
    rec_ref = darshan_lookup_record_ref(posix_runtime->fd_hash, &fd, sizeof(int));
    if(rec_ref)
Shane Snyder's avatar
Shane Snyder committed
1183
    {
1184 1185 1186
        rec_ref->last_byte_written = 0;
        rec_ref->last_byte_read = 0;
        rec_ref->file_rec->fcounters[POSIX_F_CLOSE_TIMESTAMP] =
1187 1188
            darshan_core_wtime();
        DARSHAN_TIMER_INC_NO_OVERLAP(
1189 1190 1191
            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
1192
    }
1193
    POSIX_POST_RECORD();
1194 1195 1196 1197

    return(ret);
}

1198 1199
int DARSHAN_DECL(fclose)(FILE *fp)
{
1200 1201
    int ret;
    struct posix_file_record_ref *rec_ref;
1202 1203 1204 1205 1206 1207 1208 1209 1210
    int fd = fileno(fp);
    double tm1, tm2;

    MAP_OR_FAIL(fclose);

    tm1 = darshan_core_wtime();
    ret = __real_fclose(fp);
    tm2 = darshan_core_wtime();

1211
    POSIX_PRE_RECORD();
1212 1213
    rec_ref = darshan_lookup_record_ref(posix_runtime->fd_hash, &fd, sizeof(int));
    if(rec_ref)
1214
    {
1215 1216 1217
        rec_ref->last_byte_written = 0;
        rec_ref->last_byte_read = 0;
        rec_ref->file_rec->fcounters[POSIX_F_CLOSE_TIMESTAMP] =
1218 1219
            darshan_core_wtime();
        DARSHAN_TIMER_INC_NO_OVERLAP(
1220 1221 1222
            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));
1223
    }
1224
    POSIX_POST_RECORD();
1225 1226 1227 1228

    return(ret);
}

1229 1230 1231 1232 1233 1234 1235 1236 1237
int DARSHAN_DECL(aio_read)(struct aiocb *aiocbp)
{
    int ret;

    MAP_OR_FAIL(aio_read);

    ret = __real_aio_read(aiocbp);
    if(ret == 0)
    {
1238
        POSIX_PRE_RECORD();
1239
        posix_aio_tracker_add(aiocbp->aio_fildes, aiocbp);
1240
        POSIX_POST_RECORD();
1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254
    }

    return(ret);
}

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

    MAP_OR_FAIL(aio_write);