darshan-posix.c 42.5 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

#include "darshan.h"
28
#include "darshan-core.h"
29

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

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

#define DARSHAN_DECL(__name) __wrap_ ## __name

42 43 44 45
#define MAP_OR_FAIL(func)

#define DARSHAN_MPI_CALL(func) func

46 47 48 49 50 51 52 53 54 55 56 57
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));
58
DARSHAN_FORWARD_DECL(pwrite64, ssize_t, (int fd, const void *buf, size_t count, off64_t offset));
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
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
77
DARSHAN_FORWARD_DECL(aio_read, int, (struct aiocb *aiocbp));
78
DARSHAN_FORWARD_DECL(aio_read64, int, (struct aiocb64 *aiocbp));
Philip Carns's avatar
Philip Carns committed
79
DARSHAN_FORWARD_DECL(aio_write, int, (struct aiocb *aiocbp));
80
DARSHAN_FORWARD_DECL(aio_write64, int, (struct aiocb64 *aiocbp));
Philip Carns's avatar
Philip Carns committed
81
DARSHAN_FORWARD_DECL(lio_listio, int, (int mode, struct aiocb *const aiocb_list[], int nitems, struct sigevent *sevp));
82
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
83
DARSHAN_FORWARD_DECL(aio_return, ssize_t, (struct aiocb *aiocbp));
84
DARSHAN_FORWARD_DECL(aio_return64, ssize_t, (struct aiocb64 *aiocbp));
85

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

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

109 110 111 112 113
static int darshan_mem_alignment = 1;

static int posix_mod_initialized = 0;
static int posix_mod_mem_limit = 0;
static pthread_mutex_t posix_mod_mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
114 115
static struct darshan_module_funcs posix_mod_funcs = 
{
116

117
};
118

119
static void posix_runtime_initialize(void);
120
static double posix_wtime(void);
121 122 123 124

#define POSIX_LOCK() pthread_mutex_lock(&posix_mod_mutex)
#define POSIX_UNLOCK() pthread_mutex_unlock(&posix_mod_mutex)

125
static void cp_access_counter(struct darshan_file_runtime* file, ssize_t size,     enum cp_counter_type type);
126 127
static void darshan_aio_tracker_add(int fd, void *aiocbp);
static struct darshan_aio_tracker* darshan_aio_tracker_del(int fd, void *aiocbp);
128

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

180
#define CP_RECORD_READ(__ret, __fd, __count, __pread_flag, __pread_offset, __aligned, __stream_flag, __tm1, __tm2) do{ \
181
    size_t stride; \
182
    int64_t this_offset; \
183 184
    struct darshan_file_runtime* file; \
    int64_t file_alignment; \
185
    double __elapsed = __tm2-__tm1; \
186 187 188
    if(__ret < 0) break; \
    file = darshan_file_by_fd(__fd); \
    if(!file) break; \
189 190 191 192
    if(__pread_flag)\
        this_offset = __pread_offset; \
    else \
        this_offset = file->offset; \
193
    file_alignment = CP_VALUE(file, CP_FILE_ALIGNMENT); \
194
    if(this_offset > file->last_byte_read) \
195
        CP_INC(file, CP_SEQ_READS, 1); \
196
    if(this_offset == (file->last_byte_read + 1)) \
197
        CP_INC(file, CP_CONSEC_READS, 1); \
198
    if(this_offset > 0 && this_offset > file->last_byte_read \
199
        && file->last_byte_read != 0) \
200
        stride = this_offset - file->last_byte_read - 1; \
201 202
    else \
        stride = 0; \
203 204 205
    file->last_byte_read = this_offset + __ret - 1; \
    CP_MAX(file, CP_MAX_BYTE_READ, (this_offset + __ret -1)); \
    file->offset = this_offset + __ret; \
206 207 208 209 210 211 212 213 214
    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
215
    if(file_alignment > 0 && (this_offset % file_alignment) != 0) \
216 217 218 219 220
        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; \
221
    CP_F_INC_NO_OVERLAP(file, __tm1, __tm2, file->last_posix_read_end, CP_F_POSIX_READ_TIME); \
222 223 224
    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); \
225 226 227
    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); } \
228 229
} while(0)

230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247
#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)

    
248
#define CP_RECORD_STAT(__file, __statbuf, __tm1, __tm2) do { \
249
    if(!CP_VALUE((__file), CP_POSIX_STATS) && !CP_VALUE((__file), CP_POSIX_OPENS)){ \
250 251 252 253
        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; \
254
    CP_F_INC_NO_OVERLAP(file, __tm1, __tm2, file->last_posix_meta_end, CP_F_POSIX_META_TIME); \
255 256 257
    CP_INC(__file, CP_POSIX_STATS, 1); \
} while(0)

Philip Carns's avatar
Philip Carns committed
258
#ifdef __CP_STAT_AT_OPEN
259
#define CP_STAT_FILE(_f, _p, _r) do { \
260
    if(!CP_VALUE((_f), CP_POSIX_STATS) && !CP_VALUE((_f), CP_POSIX_OPENS)){ \
261
        if(fstat64(_r, &cp_stat_buf) == 0) { \
Philip Carns's avatar
Philip Carns committed
262 263 264 265 266 267
            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
268
#define CP_STAT_FILE(_f, _p, _r) do { }while(0)
Philip Carns's avatar
Philip Carns committed
269
#endif
270
#endif
Philip Carns's avatar
Philip Carns committed
271

272 273 274 275 276 277 278 279 280 281 282
#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; \
283
    file = darshan_file_by_name_setfd(__path, __ret); \
284
    if(!file) break; \
285
    CP_STAT_FILE(file, __path, __ret); \
286 287 288 289 290 291 292 293 294 295 296
    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
297
        CP_F_SET(file, CP_F_OPEN_TIMESTAMP, __tm1); \
298
    CP_F_INC_NO_OVERLAP(file, __tm1, __tm2, file->last_posix_meta_end, CP_F_POSIX_META_TIME); \
299 300
} while (0)

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

308 309
    MAP_OR_FAIL(close);

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

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

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

    POSIX_UNLOCK();    
330 331 332 333

    return(ret);
}

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

342 343
    MAP_OR_FAIL(fclose);

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

    return(ret);
}


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

370 371
    MAP_OR_FAIL(fsync);

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

    if(ret < 0)
        return(ret);

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

    return(ret);
}

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

397 398
    MAP_OR_FAIL(fdatasync);

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

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

    return(ret);
}


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

424 425
    MAP_OR_FAIL(mmap64);

426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441
    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);
}


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

448 449
    MAP_OR_FAIL(mmap);

450 451 452 453 454 455 456 457 458 459 460 461 462 463 464
    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);
}

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

470 471
    MAP_OR_FAIL(creat);

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

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

    return(ret);
}

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

488 489
    MAP_OR_FAIL(creat64);

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

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

    return(ret);
}

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

507 508
    MAP_OR_FAIL(open64);

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

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

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

    return(ret);
}
533
#endif
534

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

541 542
    MAP_OR_FAIL(open);

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

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

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

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

    return(ret);
}

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

577 578
    MAP_OR_FAIL(fopen64);

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

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

    return(ret);
}

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

600 601
    MAP_OR_FAIL(fopen);

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

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

    return(ret);
}

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

622 623
    MAP_OR_FAIL(__xstat64);

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

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

    return(ret);
}

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

642 643
    MAP_OR_FAIL(__lxstat64);

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

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

    return(ret);
}

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

663 664
    MAP_OR_FAIL(__fxstat64);

665
    tm1 = darshan_core_wtime();
666
    ret = __real___fxstat64(vers, fd, buf);
667
    tm2 = darshan_core_wtime();
668 669 670 671 672 673 674 675 676 677 678
    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)
    {
679
        CP_RECORD_STAT(file, buf, tm1, tm2);
680 681 682 683 684 685 686
    }
    CP_UNLOCK();

    return(ret);
}


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

692 693
    MAP_OR_FAIL(__xstat);

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

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

    return(ret);
}

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

712 713
    MAP_OR_FAIL(__lxstat);

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

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

    return(ret);
}

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

733 734
    MAP_OR_FAIL(__fxstat);

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

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

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

    return(ret);
}

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

762 763
    MAP_OR_FAIL(pread64);

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

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

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

782 783
    MAP_OR_FAIL(pread);

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

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


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

803 804
    MAP_OR_FAIL(pwrite);

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

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

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

823 824
    MAP_OR_FAIL(pwrite64);

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

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

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

844 845
    MAP_OR_FAIL(readv);

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

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

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

868 869
    MAP_OR_FAIL(writev);

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

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

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

891 892
    MAP_OR_FAIL(fread);

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

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

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

914 915
    MAP_OR_FAIL(read);

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

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

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

934 935
    MAP_OR_FAIL(write);

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

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

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

954 955
    MAP_OR_FAIL(fwrite);

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

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

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

977