darshan-posix.c 39.1 KB
Newer Older
1 2 3 4 5
/*
 *  (C) 2009 by Argonne National Laboratory.
 *      See COPYRIGHT in top-level directory.
 */

6
#include "darshan-runtime-config.h"
7 8 9 10 11 12 13 14 15 16 17 18 19 20
#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>
21
#include <libgen.h>
22
#include <limits.h>
Philip Carns's avatar
Philip Carns committed
23
#include <aio.h>
24 25
#define __USE_GNU
#include <pthread.h>
26 27 28

#include "darshan.h"

29
#ifndef HAVE_OFF64_T
30 31
typedef int64_t off64_t;
#endif
32 33 34
#ifndef HAVE_AIOCB64
#define aiocb64 aiocb
#endif
35

36 37 38 39 40
#define DARSHAN_FORWARD_DECL(name,ret,args) \
  extern ret __real_ ## name args;

#define DARSHAN_DECL(__name) __wrap_ ## __name

41 42 43 44
#define MAP_OR_FAIL(func)

#define DARSHAN_MPI_CALL(func) func

45 46 47 48 49 50 51 52 53 54 55 56
DARSHAN_FORWARD_DECL(creat, int, (const char* path, mode_t mode));
DARSHAN_FORWARD_DECL(creat64, int, (const char* path, mode_t mode));
DARSHAN_FORWARD_DECL(open, int, (const char *path, int flags, ...));
DARSHAN_FORWARD_DECL(open64, int, (const char *path, int flags, ...));
DARSHAN_FORWARD_DECL(close, int, (int fd));
DARSHAN_FORWARD_DECL(write, ssize_t, (int fd, const void *buf, size_t count));
DARSHAN_FORWARD_DECL(read, ssize_t, (int fd, void *buf, size_t count));
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(pread, ssize_t, (int fd, 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(pwrite, ssize_t, (int fd, const void *buf, size_t count, off_t offset));
57
DARSHAN_FORWARD_DECL(pwrite64, ssize_t, (int fd, const void *buf, size_t count, off64_t offset));
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
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));
DARSHAN_FORWARD_DECL(__fxstat, int, (int vers, int fd, struct stat *buf));
DARSHAN_FORWARD_DECL(__fxstat64, int, (int vers, int fd, 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(__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(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));
DARSHAN_FORWARD_DECL(fopen, FILE*, (const char *path, const char *mode));
DARSHAN_FORWARD_DECL(fopen64, FILE*, (const char *path, const char *mode));
DARSHAN_FORWARD_DECL(fclose, int, (FILE *fp));
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(fseek, int, (FILE *stream, long offset, int whence));
DARSHAN_FORWARD_DECL(fsync, int, (int fd));
DARSHAN_FORWARD_DECL(fdatasync, int, (int fd));
Philip Carns's avatar
Philip Carns committed
76
DARSHAN_FORWARD_DECL(aio_read, int, (struct aiocb *aiocbp));
77
DARSHAN_FORWARD_DECL(aio_read64, int, (struct aiocb64 *aiocbp));
Philip Carns's avatar
Philip Carns committed
78
DARSHAN_FORWARD_DECL(aio_write, int, (struct aiocb *aiocbp));
79
DARSHAN_FORWARD_DECL(aio_write64, int, (struct aiocb64 *aiocbp));
Philip Carns's avatar
Philip Carns committed
80
DARSHAN_FORWARD_DECL(lio_listio, int, (int mode, struct aiocb *const aiocb_list[], int nitems, struct sigevent *sevp));
81
DARSHAN_FORWARD_DECL(lio_listio64, int, (int mode, struct aiocb64 *const aiocb_list[], int nitems, struct sigevent *sevp));
Philip Carns's avatar
Philip Carns committed
82
DARSHAN_FORWARD_DECL(aio_return, ssize_t, (struct aiocb *aiocbp));
83
DARSHAN_FORWARD_DECL(aio_return64, ssize_t, (struct aiocb64 *aiocbp));
84

85 86 87 88
/* struct to track information about aio operations in flight */
struct darshan_aio_tracker
{
    double tm1;
89
    void *aiocbp;
90 91 92
    struct darshan_aio_tracker* next;
};

93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
/* these are paths that we will not trace */
static char* exclusions[] = {
"/etc/",
"/dev/",
"/usr/",
"/bin/",
"/boot/",
"/lib/",
"/opt/",
"/sbin/",
"/sys/",
"/proc/",
NULL
};

108 109 110 111
static int darshan_mem_alignment = 1;

static int posix_mod_initialized = 0;
static pthread_mutex_t posix_mod_mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
112

113
static void posix_runtime_initialize(void);
114
static double posix_wtime(void);
115

116 117 118
static void posix_prepare_for_shutdown(void);
static void posix_get_output_data(void **buffer, int size);

119 120 121
#define POSIX_LOCK() pthread_mutex_lock(&posix_mod_mutex)
#define POSIX_UNLOCK() pthread_mutex_unlock(&posix_mod_mutex)

122
#if 0
123
static void cp_access_counter(struct darshan_file_runtime* file, ssize_t size,     enum cp_counter_type type);
124 125
static void darshan_aio_tracker_add(int fd, void *aiocbp);
static struct darshan_aio_tracker* darshan_aio_tracker_del(int fd, void *aiocbp);
126
#endif
127

128
#if 0
Philip Carns's avatar
Philip Carns committed
129
#define CP_RECORD_WRITE(__ret, __fd, __count, __pwrite_flag, __pwrite_offset, __aligned, __stream_flag, __tm1, __tm2) do{ \
130
    size_t stride; \
Philip Carns's avatar
Philip Carns committed
131
    int64_t this_offset; \
132 133
    int64_t file_alignment; \
    struct darshan_file_runtime* file; \
134
    double __elapsed = __tm2-__tm1; \
135 136 137
    if(__ret < 0) break; \
    file = darshan_file_by_fd(__fd); \
    if(!file) break; \
Philip Carns's avatar
Philip Carns committed
138 139 140 141
    if(__pwrite_flag) \
        this_offset = __pwrite_offset; \
    else \
        this_offset = file->offset; \
142
    file_alignment = CP_VALUE(file, CP_FILE_ALIGNMENT); \
Philip Carns's avatar
Philip Carns committed
143
    if(this_offset > file->last_byte_written) \
144
        CP_INC(file, CP_SEQ_WRITES, 1); \
Philip Carns's avatar
Philip Carns committed
145
    if(this_offset == (file->last_byte_written + 1)) \
146
        CP_INC(file, CP_CONSEC_WRITES, 1); \
Philip Carns's avatar
Philip Carns committed
147
    if(this_offset > 0 && this_offset > file->last_byte_written \
148
        && file->last_byte_written != 0) \
Philip Carns's avatar
Philip Carns committed
149
        stride = this_offset - file->last_byte_written - 1; \
150 151
    else \
        stride = 0; \
Philip Carns's avatar
Philip Carns committed
152 153 154
    file->last_byte_written = this_offset + __ret - 1; \
    file->offset = this_offset + __ret; \
    CP_MAX(file, CP_MAX_BYTE_WRITTEN, (this_offset + __ret -1)); \
155 156 157 158 159 160 161 162 163
    CP_INC(file, CP_BYTES_WRITTEN, __ret); \
    if(__stream_flag) \
        CP_INC(file, CP_POSIX_FWRITES, 1); \
    else \
        CP_INC(file, CP_POSIX_WRITES, 1); \
    CP_BUCKET_INC(file, CP_SIZE_WRITE_0_100, __ret); \
    cp_access_counter(file, stride, CP_COUNTER_STRIDE); \
    if(!__aligned) \
        CP_INC(file, CP_MEM_NOT_ALIGNED, 1); \
Philip Carns's avatar
Philip Carns committed
164
    if(file_alignment > 0 && (this_offset % file_alignment) != 0) \
165 166 167 168 169
        CP_INC(file, CP_FILE_NOT_ALIGNED, 1); \
    cp_access_counter(file, __ret, CP_COUNTER_ACCESS); \
    if(file->last_io_type == CP_READ) \
        CP_INC(file, CP_RW_SWITCHES, 1); \
    file->last_io_type = CP_WRITE; \
170
    CP_F_INC_NO_OVERLAP(file, __tm1, __tm2, file->last_posix_write_end, CP_F_POSIX_WRITE_TIME); \
171 172 173
    if(CP_F_VALUE(file, CP_F_WRITE_START_TIMESTAMP) == 0) \
        CP_F_SET(file, CP_F_WRITE_START_TIMESTAMP, __tm1); \
    CP_F_SET(file, CP_F_WRITE_END_TIMESTAMP, __tm2); \
174 175 176
    if(CP_F_VALUE(file, CP_F_MAX_WRITE_TIME) < __elapsed){ \
        CP_F_SET(file, CP_F_MAX_WRITE_TIME, __elapsed); \
        CP_SET(file, CP_MAX_WRITE_TIME_SIZE, __ret); } \
177 178
} while(0)

179
#define CP_RECORD_READ(__ret, __fd, __count, __pread_flag, __pread_offset, __aligned, __stream_flag, __tm1, __tm2) do{ \
180
    size_t stride; \
181
    int64_t this_offset; \
182 183
    struct darshan_file_runtime* file; \
    int64_t file_alignment; \
184
    double __elapsed = __tm2-__tm1; \
185 186 187
    if(__ret < 0) break; \
    file = darshan_file_by_fd(__fd); \
    if(!file) break; \
188 189 190 191
    if(__pread_flag)\
        this_offset = __pread_offset; \
    else \
        this_offset = file->offset; \
192
    file_alignment = CP_VALUE(file, CP_FILE_ALIGNMENT); \
193
    if(this_offset > file->last_byte_read) \
194
        CP_INC(file, CP_SEQ_READS, 1); \
195
    if(this_offset == (file->last_byte_read + 1)) \
196
        CP_INC(file, CP_CONSEC_READS, 1); \
197
    if(this_offset > 0 && this_offset > file->last_byte_read \
198
        && file->last_byte_read != 0) \
199
        stride = this_offset - file->last_byte_read - 1; \
200 201
    else \
        stride = 0; \
202 203 204
    file->last_byte_read = this_offset + __ret - 1; \
    CP_MAX(file, CP_MAX_BYTE_READ, (this_offset + __ret -1)); \
    file->offset = this_offset + __ret; \
205 206 207 208 209 210 211 212 213
    CP_INC(file, CP_BYTES_READ, __ret); \
    if(__stream_flag)\
        CP_INC(file, CP_POSIX_FREADS, 1); \
    else\
        CP_INC(file, CP_POSIX_READS, 1); \
    CP_BUCKET_INC(file, CP_SIZE_READ_0_100, __ret); \
    cp_access_counter(file, stride, CP_COUNTER_STRIDE); \
    if(!__aligned) \
        CP_INC(file, CP_MEM_NOT_ALIGNED, 1); \
Philip Carns's avatar
Philip Carns committed
214
    if(file_alignment > 0 && (this_offset % file_alignment) != 0) \
215 216 217 218 219
        CP_INC(file, CP_FILE_NOT_ALIGNED, 1); \
    cp_access_counter(file, __ret, CP_COUNTER_ACCESS); \
    if(file->last_io_type == CP_WRITE) \
        CP_INC(file, CP_RW_SWITCHES, 1); \
    file->last_io_type = CP_READ; \
220
    CP_F_INC_NO_OVERLAP(file, __tm1, __tm2, file->last_posix_read_end, CP_F_POSIX_READ_TIME); \
221 222 223
    if(CP_F_VALUE(file, CP_F_READ_START_TIMESTAMP) == 0) \
        CP_F_SET(file, CP_F_READ_START_TIMESTAMP, __tm1); \
    CP_F_SET(file, CP_F_READ_END_TIMESTAMP, __tm2); \
224 225 226
    if(CP_F_VALUE(file, CP_F_MAX_READ_TIME) < __elapsed){ \
        CP_F_SET(file, CP_F_MAX_READ_TIME, __elapsed); \
        CP_SET(file, CP_MAX_READ_TIME_SIZE, __ret); } \
227 228
} while(0)

229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246
#define CP_LOOKUP_RECORD_STAT(__path, __statbuf, __tm1, __tm2) do { \
    char* exclude; \
    int tmp_index = 0; \
    struct darshan_file_runtime* file; \
    while((exclude = exclusions[tmp_index])) { \
        if(!(strncmp(exclude, __path, strlen(exclude)))) \
            break; \
        tmp_index++; \
    } \
    if(exclude) break; \
    file = darshan_file_by_name(__path); \
    if (file) \
    { \
        CP_RECORD_STAT(file, __statbuf, __tm1, __tm2); \
    } \
} while(0)

    
247
#define CP_RECORD_STAT(__file, __statbuf, __tm1, __tm2) do { \
248
    if(!CP_VALUE((__file), CP_POSIX_STATS) && !CP_VALUE((__file), CP_POSIX_OPENS)){ \
249 250 251 252
        CP_SET((__file), CP_FILE_ALIGNMENT, (__statbuf)->st_blksize); \
        CP_SET((__file), CP_SIZE_AT_OPEN, (__statbuf)->st_size); \
    }\
    (__file)->log_file->rank = my_rank; \
253
    CP_F_INC_NO_OVERLAP(file, __tm1, __tm2, file->last_posix_meta_end, CP_F_POSIX_META_TIME); \
254 255 256
    CP_INC(__file, CP_POSIX_STATS, 1); \
} while(0)

Philip Carns's avatar
Philip Carns committed
257
#ifdef __CP_STAT_AT_OPEN
258
#define CP_STAT_FILE(_f, _p, _r) do { \
259
    if(!CP_VALUE((_f), CP_POSIX_STATS) && !CP_VALUE((_f), CP_POSIX_OPENS)){ \
260
        if(fstat64(_r, &cp_stat_buf) == 0) { \
Philip Carns's avatar
Philip Carns committed
261 262 263 264 265 266
            CP_SET(_f, CP_FILE_ALIGNMENT, cp_stat_buf.st_blksize); \
            CP_SET(_f, CP_SIZE_AT_OPEN, cp_stat_buf.st_size); \
        }\
    }\
}while(0)
#else
267
#define CP_STAT_FILE(_f, _p, _r) do { }while(0)
Philip Carns's avatar
Philip Carns committed
268 269
#endif

270 271 272 273 274 275 276 277 278 279 280
#define CP_RECORD_OPEN(__ret, __path, __mode, __stream_flag, __tm1, __tm2) do { \
    struct darshan_file_runtime* file; \
    char* exclude; \
    int tmp_index = 0; \
    if(__ret < 0) break; \
    while((exclude = exclusions[tmp_index])) { \
        if(!(strncmp(exclude, __path, strlen(exclude)))) \
            break; \
        tmp_index++; \
    } \
    if(exclude) break; \
281
    file = darshan_file_by_name_setfd(__path, __ret); \
282
    if(!file) break; \
283
    CP_STAT_FILE(file, __path, __ret); \
284 285 286 287 288 289 290 291 292 293 294
    file->log_file->rank = my_rank; \
    if(__mode) \
        CP_SET(file, CP_MODE, __mode); \
    file->offset = 0; \
    file->last_byte_written = 0; \
    file->last_byte_read = 0; \
    if(__stream_flag)\
        CP_INC(file, CP_POSIX_FOPENS, 1); \
    else \
        CP_INC(file, CP_POSIX_OPENS, 1); \
    if(CP_F_VALUE(file, CP_F_OPEN_TIMESTAMP) == 0) \
Philip Carns's avatar
Philip Carns committed
295
        CP_F_SET(file, CP_F_OPEN_TIMESTAMP, __tm1); \
296
    CP_F_INC_NO_OVERLAP(file, __tm1, __tm2, file->last_posix_meta_end, CP_F_POSIX_META_TIME); \
297
} while (0)
298
#endif
299

300
int DARSHAN_DECL(close)(int fd)
301 302 303 304 305 306
{
    struct darshan_file_runtime* file;
    int tmp_fd = fd;
    double tm1, tm2;
    int ret;

307 308
    MAP_OR_FAIL(close);

309
    tm1 = darshan_core_wtime();
310
    ret = __real_close(fd);
311
    tm2 = darshan_core_wtime();
312

313 314 315 316
    POSIX_LOCK();
    posix_runtime_initialize();

#if 0
317 318 319 320 321
    file = darshan_file_by_fd(tmp_fd);
    if(file)
    {
        file->last_byte_written = 0;
        file->last_byte_read = 0;
322
        CP_F_SET(file, CP_F_CLOSE_TIMESTAMP, posix_wtime());
323
        CP_F_INC_NO_OVERLAP(file, tm1, tm2, file->last_posix_meta_end, CP_F_POSIX_META_TIME);
324
        darshan_file_close_fd(tmp_fd);
325
    }
326 327 328
#endif

    POSIX_UNLOCK();    
329 330 331 332

    return(ret);
}

333
#if 0
334
int DARSHAN_DECL(fclose)(FILE *fp)
335 336 337 338 339 340
{
    struct darshan_file_runtime* file;
    int tmp_fd = fileno(fp);
    double tm1, tm2;
    int ret;

341 342
    MAP_OR_FAIL(fclose);

343
    tm1 = darshan_core_wtime();
344
    ret = __real_fclose(fp);
345
    tm2 = darshan_core_wtime();
346 347 348 349 350 351 352
    
    CP_LOCK();
    file = darshan_file_by_fd(tmp_fd);
    if(file)
    {
        file->last_byte_written = 0;
        file->last_byte_read = 0;
353
        CP_F_SET(file, CP_F_CLOSE_TIMESTAMP, posix_wtime());
354
        CP_F_INC_NO_OVERLAP(file, tm1, tm2, file->last_posix_meta_end, CP_F_POSIX_META_TIME);
355
        darshan_file_close_fd(tmp_fd);
356 357 358 359 360 361 362
    }
    CP_UNLOCK();

    return(ret);
}


363
int DARSHAN_DECL(fsync)(int fd)
364 365 366 367 368
{
    int ret;
    struct darshan_file_runtime* file;
    double tm1, tm2;

369 370
    MAP_OR_FAIL(fsync);

371
    tm1 = darshan_core_wtime();
372
    ret = __real_fsync(fd);
373
    tm2 = darshan_core_wtime();
374 375 376 377 378 379 380 381

    if(ret < 0)
        return(ret);

    CP_LOCK();
    file = darshan_file_by_fd(fd);
    if(file)
    {
382
        CP_F_INC_NO_OVERLAP(file, tm1, tm2, file->last_posix_write_end, CP_F_POSIX_WRITE_TIME); \
383 384 385 386 387 388 389
        CP_INC(file, CP_POSIX_FSYNCS, 1);
    }
    CP_UNLOCK();

    return(ret);
}

390
int DARSHAN_DECL(fdatasync)(int fd)
391 392 393 394 395
{
    int ret;
    struct darshan_file_runtime* file;
    double tm1, tm2;

396 397
    MAP_OR_FAIL(fdatasync);

398
    tm1 = darshan_core_wtime();
399
    ret = __real_fdatasync(fd);
400
    tm2 = darshan_core_wtime();
401 402 403 404 405 406 407
    if(ret < 0)
        return(ret);

    CP_LOCK();
    file = darshan_file_by_fd(fd);
    if(file)
    {
408
        CP_F_INC_NO_OVERLAP(file, tm1, tm2, file->last_posix_write_end, CP_F_POSIX_WRITE_TIME); \
409 410 411 412 413 414 415 416
        CP_INC(file, CP_POSIX_FDSYNCS, 1);
    }
    CP_UNLOCK();

    return(ret);
}


417
void* DARSHAN_DECL(mmap64)(void *addr, size_t length, int prot, int flags,
418 419 420 421 422
    int fd, off64_t offset)
{
    void* ret;
    struct darshan_file_runtime* file;

423 424
    MAP_OR_FAIL(mmap64);

425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440
    ret = __real_mmap64(addr, length, prot, flags, fd, offset);
    if(ret == MAP_FAILED)
        return(ret);

    CP_LOCK();
    file = darshan_file_by_fd(fd);
    if(file)
    {
        CP_INC(file, CP_POSIX_MMAPS, 1);
    }
    CP_UNLOCK();

    return(ret);
}


441
void* DARSHAN_DECL(mmap)(void *addr, size_t length, int prot, int flags,
442 443 444 445 446
    int fd, off_t offset)
{
    void* ret;
    struct darshan_file_runtime* file;

447 448
    MAP_OR_FAIL(mmap);

449 450 451 452 453 454 455 456 457 458 459 460 461 462 463
    ret = __real_mmap(addr, length, prot, flags, fd, offset);
    if(ret == MAP_FAILED)
        return(ret);

    CP_LOCK();
    file = darshan_file_by_fd(fd);
    if(file)
    {
        CP_INC(file, CP_POSIX_MMAPS, 1);
    }
    CP_UNLOCK();

    return(ret);
}

464
int DARSHAN_DECL(creat)(const char* path, mode_t mode)
465 466 467 468
{
    int ret;
    double tm1, tm2;

469 470
    MAP_OR_FAIL(creat);

471
    tm1 = darshan_core_wtime();
472
    ret = __real_creat(path, mode);
473
    tm2 = darshan_core_wtime();
474 475 476 477 478 479 480 481

    CP_LOCK();
    CP_RECORD_OPEN(ret, path, mode, 0, tm1, tm2);
    CP_UNLOCK();

    return(ret);
}

482
int DARSHAN_DECL(creat64)(const char* path, mode_t mode)
483 484 485 486
{
    int ret;
    double tm1, tm2;

487 488
    MAP_OR_FAIL(creat64);

489
    tm1 = darshan_core_wtime();
490
    ret = __real_creat64(path, mode);
491
    tm2 = darshan_core_wtime();
492 493 494 495 496 497 498 499

    CP_LOCK();
    CP_RECORD_OPEN(ret, path, mode, 0, tm1, tm2);
    CP_UNLOCK();

    return(ret);
}

500
int DARSHAN_DECL(open64)(const char* path, int flags, ...)
501 502 503 504 505
{
    int mode = 0;
    int ret;
    double tm1, tm2;

506 507
    MAP_OR_FAIL(open64);

508 509 510 511 512 513 514
    if (flags & O_CREAT) 
    {
        va_list arg;
        va_start(arg, flags);
        mode = va_arg(arg, int);
        va_end(arg);

515
        tm1 = darshan_core_wtime();
516
        ret = __real_open64(path, flags, mode);
517
        tm2 = darshan_core_wtime();
518 519 520
    }
    else
    {
521
        tm1 = darshan_core_wtime();
522
        ret = __real_open64(path, flags);
523
        tm2 = darshan_core_wtime();
524 525 526 527 528 529 530 531
    }

    CP_LOCK();
    CP_RECORD_OPEN(ret, path, mode, 0, tm1, tm2);
    CP_UNLOCK();

    return(ret);
}
532
#endif
533

534
int DARSHAN_DECL(open)(const char *path, int flags, ...)
535 536 537 538 539
{
    int mode = 0;
    int ret;
    double tm1, tm2;

540 541
    MAP_OR_FAIL(open);

542 543 544 545 546 547 548
    if (flags & O_CREAT) 
    {
        va_list arg;
        va_start(arg, flags);
        mode = va_arg(arg, int);
        va_end(arg);

549
        tm1 = darshan_core_wtime();
550
        ret = __real_open(path, flags, mode);
551
        tm2 = darshan_core_wtime();
552 553 554
    }
    else
    {
555
        tm1 = darshan_core_wtime();
556
        ret = __real_open(path, flags);
557
        tm2 = darshan_core_wtime();
558 559
    }

560 561 562 563 564
    POSIX_LOCK();
    posix_runtime_initialize();

//    POSIX_RECORD_OPEN(ret, path, mode, 0, tm1, tm2);
    POSIX_UNLOCK();
565 566 567 568

    return(ret);
}

569
#if 0
570
FILE* DARSHAN_DECL(fopen64)(const char *path, const char *mode)
571 572 573 574 575
{
    FILE* ret;
    int fd;
    double tm1, tm2;

576 577
    MAP_OR_FAIL(fopen64);

578
    tm1 = darshan_core_wtime();
579
    ret = __real_fopen64(path, mode);
580
    tm2 = darshan_core_wtime();
581 582 583 584 585 586 587 588 589 590 591 592
    if(ret == 0)
        fd = -1;
    else
        fd = fileno(ret);

    CP_LOCK();
    CP_RECORD_OPEN(fd, path, 0, 1, tm1, tm2);
    CP_UNLOCK();

    return(ret);
}

593
FILE* DARSHAN_DECL(fopen)(const char *path, const char *mode)
594 595 596 597 598
{
    FILE* ret;
    int fd;
    double tm1, tm2;

599 600
    MAP_OR_FAIL(fopen);

601
    tm1 = darshan_core_wtime();
602
    ret = __real_fopen(path, mode);
603
    tm2 = darshan_core_wtime();
604 605 606 607 608 609 610 611 612 613 614 615
    if(ret == 0)
        fd = -1;
    else
        fd = fileno(ret);

    CP_LOCK();
    CP_RECORD_OPEN(fd, path, 0, 1, tm1, tm2);
    CP_UNLOCK();

    return(ret);
}

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

621 622
    MAP_OR_FAIL(__xstat64);

623
    tm1 = darshan_core_wtime();
624
    ret = __real___xstat64(vers, path, buf);
625
    tm2 = darshan_core_wtime();
626 627 628 629
    if(ret < 0 || !S_ISREG(buf->st_mode))
        return(ret);

    CP_LOCK();
630
    CP_LOOKUP_RECORD_STAT(path, buf, tm1, tm2);
631 632 633 634 635
    CP_UNLOCK();

    return(ret);
}

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

641 642
    MAP_OR_FAIL(__lxstat64);

643
    tm1 = darshan_core_wtime();
644
    ret = __real___lxstat64(vers, path, buf);
645
    tm2 = darshan_core_wtime();
646 647 648 649
    if(ret < 0 || !S_ISREG(buf->st_mode))
        return(ret);

    CP_LOCK();
650
    CP_LOOKUP_RECORD_STAT(path, buf, tm1, tm2);
651 652 653 654 655
    CP_UNLOCK();

    return(ret);
}

656
int DARSHAN_DECL(__fxstat64)(int vers, int fd, struct stat64 *buf)
657 658 659 660 661
{
    int ret;
    struct darshan_file_runtime* file;
    double tm1, tm2;

662 663
    MAP_OR_FAIL(__fxstat64);

664
    tm1 = darshan_core_wtime();
665
    ret = __real___fxstat64(vers, fd, buf);
666
    tm2 = darshan_core_wtime();
667 668 669 670 671 672 673 674 675 676 677
    if(ret < 0 || !S_ISREG(buf->st_mode))
        return(ret);

    /* skip logging if this was triggered internally */
    if(buf == &cp_stat_buf)
        return(ret);

    CP_LOCK();
    file = darshan_file_by_fd(fd);
    if(file)
    {
678
        CP_RECORD_STAT(file, buf, tm1, tm2);
679 680 681 682 683 684 685
    }
    CP_UNLOCK();

    return(ret);
}


686
int DARSHAN_DECL(__xstat)(int vers, const char *path, struct stat *buf)
687 688 689 690
{
    int ret;
    double tm1, tm2;

691 692
    MAP_OR_FAIL(__xstat);

693
    tm1 = darshan_core_wtime();
694
    ret = __real___xstat(vers, path, buf);
695
    tm2 = darshan_core_wtime();
696 697 698 699
    if(ret < 0 || !S_ISREG(buf->st_mode))
        return(ret);

    CP_LOCK();
700
    CP_LOOKUP_RECORD_STAT(path, buf, tm1, tm2);
701 702 703 704 705
    CP_UNLOCK();

    return(ret);
}

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

711 712
    MAP_OR_FAIL(__lxstat);

713
    tm1 = darshan_core_wtime();
714
    ret = __real___lxstat(vers, path, buf);
715
    tm2 = darshan_core_wtime();
716 717 718 719
    if(ret < 0 || !S_ISREG(buf->st_mode))
        return(ret);

    CP_LOCK();
720
    CP_LOOKUP_RECORD_STAT(path, buf, tm1, tm2);
721 722 723 724 725
    CP_UNLOCK();

    return(ret);
}

726
int DARSHAN_DECL(__fxstat)(int vers, int fd, struct stat *buf)
727 728 729 730 731
{
    int ret;
    struct darshan_file_runtime* file;
    double tm1, tm2;

732 733
    MAP_OR_FAIL(__fxstat);

734
    tm1 = darshan_core_wtime();
735
    ret = __real___fxstat(vers, fd, buf);
736
    tm2 = darshan_core_wtime();
737 738 739 740
    if(ret < 0 || !S_ISREG(buf->st_mode))
        return(ret);

    /* skip logging if this was triggered internally */
741
    if((void*)buf == (void*)&cp_stat_buf)
742 743 744 745 746 747
        return(ret);

    CP_LOCK();
    file = darshan_file_by_fd(fd);
    if(file)
    {
748
        CP_RECORD_STAT(file, buf, tm1, tm2);
749 750 751 752 753 754
    }
    CP_UNLOCK();

    return(ret);
}

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

761 762
    MAP_OR_FAIL(pread64);

763
    if((unsigned long)buf % darshan_mem_alignment == 0)
764 765
        aligned_flag = 1;

766
    tm1 = darshan_core_wtime();
767
    ret = __real_pread64(fd, buf, count, offset);
768
    tm2 = darshan_core_wtime();
769
    CP_LOCK();
770
    CP_RECORD_READ(ret, fd, count, 1, offset, aligned_flag, 0, tm1, tm2);
771 772 773 774
    CP_UNLOCK();
    return(ret);
}

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

781 782
    MAP_OR_FAIL(pread);

783
    if((unsigned long)buf % darshan_mem_alignment == 0)
784 785
        aligned_flag = 1;

786
    tm1 = darshan_core_wtime();
787
    ret = __real_pread(fd, buf, count, offset);
788
    tm2 = darshan_core_wtime();
789
    CP_LOCK();
790
    CP_RECORD_READ(ret, fd, count, 1, offset, aligned_flag, 0, tm1, tm2);
791 792 793 794 795
    CP_UNLOCK();
    return(ret);
}


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

802 803
    MAP_OR_FAIL(pwrite);

804
    if((unsigned long)buf % darshan_mem_alignment == 0)
805 806
        aligned_flag = 1;

807
    tm1 = darshan_core_wtime();
808
    ret = __real_pwrite(fd, buf, count, offset);
809
    tm2 = darshan_core_wtime();
810
    CP_LOCK();
Philip Carns's avatar
Philip Carns committed
811
    CP_RECORD_WRITE(ret, fd, count, 1, offset, aligned_flag, 0, tm1, tm2);
812 813 814 815
    CP_UNLOCK();
    return(ret);
}

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

822 823
    MAP_OR_FAIL(pwrite64);

824
    if((unsigned long)buf % darshan_mem_alignment == 0)
825 826
        aligned_flag = 1;

827
    tm1 = darshan_core_wtime();
828
    ret = __real_pwrite64(fd, buf, count, offset);
829
    tm2 = darshan_core_wtime();
830
    CP_LOCK();
Philip Carns's avatar
Philip Carns committed
831
    CP_RECORD_WRITE(ret, fd, count, 1, offset, aligned_flag, 0, tm1, tm2);
832 833 834 835
    CP_UNLOCK();
    return(ret);
}

836
ssize_t DARSHAN_DECL(readv)(int fd, const struct iovec *iov, int iovcnt)
837 838 839 840 841 842
{
    ssize_t ret;
    int aligned_flag = 1;
    int i;
    double tm1, tm2;

843 844
    MAP_OR_FAIL(readv);

845 846
    for(i=0; i<iovcnt; i++)
    {
847
        if(((unsigned long)iov[i].iov_base % darshan_mem_alignment) != 0)
848 849 850
            aligned_flag = 0;
    }

851
    tm1 = darshan_core_wtime();
852
    ret = __real_readv(fd, iov, iovcnt);
853
    tm2 = darshan_core_wtime();
854
    CP_LOCK();
855
    CP_RECORD_READ(ret, fd, count, 0, 0, aligned_flag, 0, tm1, tm2);
856 857 858 859
    CP_UNLOCK();
    return(ret);
}

860
ssize_t DARSHAN_DECL(writev)(int fd, const struct iovec *iov, int iovcnt)
861 862 863 864 865 866
{
    ssize_t ret;
    int aligned_flag = 1;
    int i;
    double tm1, tm2;

867 868
    MAP_OR_FAIL(writev);

869 870
    for(i=0; i<iovcnt; i++)
    {
871
        if(!((unsigned long)iov[i].iov_base % darshan_mem_alignment == 0))
872 873 874
            aligned_flag = 0;
    }

875
    tm1 = darshan_core_wtime();
876
    ret = __real_writev(fd, iov, iovcnt);
877
    tm2 = darshan_core_wtime();
878
    CP_LOCK();
Philip Carns's avatar
Philip Carns committed
879
    CP_RECORD_WRITE(ret, fd, count, 0, 0, aligned_flag, 0, tm1, tm2);
880 881 882 883
    CP_UNLOCK();
    return(ret);
}

884
size_t DARSHAN_DECL(fread)(void *ptr, size_t size, size_t nmemb, FILE *stream)
885 886 887 888 889
{
    size_t ret;
    int aligned_flag = 0;
    double tm1, tm2;

890 891
    MAP_OR_FAIL(fread);

892
    if((unsigned long)ptr % darshan_mem_alignment == 0)
893 894
        aligned_flag = 1;

895
    tm1 = darshan_core_wtime();
896
    ret = __real_fread(ptr, size, nmemb, stream);
897
    tm2 = darshan_core_wtime();
898 899
    CP_LOCK();
    if(ret > 0)
900
        CP_RECORD_READ(size*ret, fileno(stream), (size*nmemb), 0, 0, aligned_flag, 1, tm1, tm2);
901
    else
902
        CP_RECORD_READ(ret, fileno(stream), (size*nmemb), 0, 0, aligned_flag, 1, tm1, tm2);
903 904 905 906
    CP_UNLOCK();
    return(ret);
}

907
ssize_t DARSHAN_DECL(read)(int fd, void *buf, size_t count)
908 909 910 911 912
{
    ssize_t ret;
    int aligned_flag = 0;
    double tm1, tm2;

913 914
    MAP_OR_FAIL(read);

915
    if((unsigned long)buf % darshan_mem_alignment == 0)
916 917
        aligned_flag = 1;

918
    tm1 = darshan_core_wtime();
919
    ret = __real_read(fd, buf, count);
920
    tm2 = darshan_core_wtime();
921
    CP_LOCK();
922
    CP_RECORD_READ(ret, fd, count, 0, 0, aligned_flag, 0, tm1, tm2);
923 924 925 926
    CP_UNLOCK();
    return(ret);
}

927
ssize_t DARSHAN_DECL(write)(int fd, const void *buf, size_t count)
928 929 930 931 932
{
    ssize_t ret;
    int aligned_flag = 0;
    double tm1, tm2;

933 934
    MAP_OR_FAIL(write);

935
    if((unsigned long)buf % darshan_mem_alignment == 0)
936 937
        aligned_flag = 1;

938
    tm1 = darshan_core_wtime();
939
    ret = __real_write(fd, buf, count);
940
    tm2 = darshan_core_wtime();
941
    CP_LOCK();
Philip Carns's avatar
Philip Carns committed
942
    CP_RECORD_WRITE(ret, fd, count, 0, 0, aligned_flag, 0, tm1, tm2);
943 944 945 946
    CP_UNLOCK();
    return(ret);
}

947
size_t DARSHAN_DECL(fwrite)(const void *ptr, size_t size, size_t nmemb, FILE *stream)
948 949 950 951 952
{
    size_t ret;
    int aligned_flag = 0;
    double tm1, tm2;

953 954
    MAP_OR_FAIL(fwrite);

955
    if((unsigned long)ptr % darshan_mem_alignment == 0)
956 957
        aligned_flag = 1;

958
    tm1 = darshan_core_wtime();
959
    ret = __real_fwrite(ptr, size, nmemb, stream);
960
    tm2 = darshan_core_wtime();
961 962
    CP_LOCK();
    if(ret > 0)
Philip Carns's avatar
Philip Carns committed
963
        CP_RECORD_WRITE(size*ret, fileno(stream), (size*nmemb), 0, 0, aligned_flag, 1, tm1, tm2);
964
    else
Philip Carns's avatar
Philip Carns committed
965
        CP_RECORD_WRITE(ret, fileno(stream), 0, 0, 0, aligned_flag, 1, tm1, tm2);
966 967 968 969
    CP_UNLOCK();
    return(ret);
}

970
off64_t DARSHAN_DECL(lseek64)(int fd, off64_t offset, int whence)
971
{
Philip Carns's avatar
Philip Carns committed
972
    off64_t ret;
973 974 975
    struct darshan_file_runtime* file;
    double tm1, tm2;

976 977
    MAP_OR_FAIL(lseek64);

978
    tm1 = darshan_core_wtime();
Philip Carns's avatar