darshan-posix-logutils.c 23.9 KB
Newer Older
Shane Snyder's avatar
Shane Snyder committed
1
/*
Shane Snyder's avatar
Shane Snyder committed
2 3 4
 * Copyright (C) 2015 University of Chicago.
 * See COPYRIGHT notice in top-level directory.
 *
Shane Snyder's avatar
Shane Snyder committed
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
 */

#define _GNU_SOURCE
#include "darshan-util-config.h"
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <stdlib.h>
#include <unistd.h>
#include <inttypes.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>

20
#include "darshan-logutils.h"
Shane Snyder's avatar
Shane Snyder committed
21

22 23 24 25 26 27 28 29 30 31 32
/* counter name strings for the POSIX module */
#define X(a) #a,
char *posix_counter_names[] = {
    POSIX_COUNTERS
};

char *posix_f_counter_names[] = {
    POSIX_F_COUNTERS
};
#undef X

33
#define DARSHAN_POSIX_FILE_SIZE_1 680
34
#define DARSHAN_POSIX_FILE_SIZE_2 648
35

36
static int darshan_log_get_posix_file(darshan_fd fd, void** posix_buf_p);
37
static int darshan_log_put_posix_file(darshan_fd fd, void* posix_buf);
38
static void darshan_log_print_posix_file(void *file_rec,
39
    char *file_name, char *mnt_pt, char *fs_type);
40
static void darshan_log_print_posix_description(int ver);
41 42
static void darshan_log_print_posix_file_diff(void *file_rec1, char *file_name1,
    void *file_rec2, char *file_name2);
43
static void darshan_log_agg_posix_files(void *rec, void *agg_rec, int init_flag);
44

45 46 47
struct darshan_mod_logutil_funcs posix_logutils =
{
    .log_get_record = &darshan_log_get_posix_file,
48
    .log_put_record = &darshan_log_put_posix_file,
49
    .log_print_record = &darshan_log_print_posix_file,
50
    .log_print_description = &darshan_log_print_posix_description,
51
    .log_print_diff = &darshan_log_print_posix_file_diff,
52
    .log_agg_records = &darshan_log_agg_posix_files,
53 54
};

55
static int darshan_log_get_posix_file(darshan_fd fd, void** posix_buf_p)
Shane Snyder's avatar
Shane Snyder committed
56
{
57
    struct darshan_posix_file *file = *((struct darshan_posix_file **)posix_buf_p);
58
    int rec_len;
Shane Snyder's avatar
Shane Snyder committed
59
    int i;
60 61
    int ret = -1;

62 63 64 65 66 67 68 69 70 71
    if(fd->mod_map[DARSHAN_POSIX_MOD].len == 0)
        return(0);

    if(*posix_buf_p == NULL)
    {
        file = malloc(sizeof(*file));
        if(!file)
            return(-1);
    }

72
    if(fd->mod_ver[DARSHAN_POSIX_MOD] == DARSHAN_POSIX_VER) 
73
    {
74 75 76 77 78
        /* log format is in current version, so we don't need to do any
         * translation of counters while reading
         */
        rec_len = sizeof(struct darshan_posix_file);
        ret = darshan_log_get_mod(fd, DARSHAN_POSIX_MOD, file, rec_len);
79
    }
80
    else
81
    {
82 83 84 85 86
        char scratch[1024] = {0};
        char *src_p, *dest_p;
        int len;

        if(fd->mod_ver[DARSHAN_POSIX_MOD] == 1)
87
        {
88 89 90 91 92 93 94 95 96 97 98
            rec_len = DARSHAN_POSIX_FILE_SIZE_1;
            ret = darshan_log_get_mod(fd, DARSHAN_POSIX_MOD, scratch, rec_len);
            if(ret != rec_len)
                goto exit;

            /* upconvert version 1 to version 2 in-place */
            dest_p = scratch + (sizeof(struct darshan_base_record) + 
                (6 * sizeof(int64_t)));
            src_p = dest_p + (4 * sizeof(int64_t));
            len = rec_len - (src_p - scratch);
            memmove(dest_p, src_p, len);
99
        }
100
        if(fd->mod_ver[DARSHAN_POSIX_MOD] <= 2)
101
        {
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
            if(fd->mod_ver[DARSHAN_POSIX_MOD] == 2)
            {
                rec_len = DARSHAN_POSIX_FILE_SIZE_2;
                ret = darshan_log_get_mod(fd, DARSHAN_POSIX_MOD, scratch, rec_len);
                if(ret != rec_len)
                    goto exit;
            }

            /* upconvert version 2 to version 3 in-place */
            dest_p = scratch + (sizeof(struct darshan_base_record) +
                (64 * sizeof(int64_t)) + (5 * sizeof(double)));
            src_p = dest_p - (2 * sizeof(double));
            len = (12 * sizeof(double));
            memmove(dest_p, src_p, len);
            /* set F_CLOSE_START and F_OPEN_END to -1 */
            *((double *)src_p) = -1;
            *((double *)(src_p + sizeof(double))) = -1;
119
        }
120 121

        memcpy(file, scratch, sizeof(struct darshan_posix_file));
122 123
    }

124
exit:
125 126 127 128 129 130
    if(*posix_buf_p == NULL)
    {
        if(ret == rec_len)
            *posix_buf_p = file;
        else
            free(file);
131
    }
Shane Snyder's avatar
Shane Snyder committed
132

133
    if(ret < 0)
134
        return(-1);
135
    else if(ret < rec_len)
136 137
        return(0);
    else
Shane Snyder's avatar
Shane Snyder committed
138
    {
139
        /* if the read was successful, do any necessary byte-swapping */
140 141
        if(fd->swap_flag)
        {
142 143
            DARSHAN_BSWAP64(&file->base_rec.id);
            DARSHAN_BSWAP64(&file->base_rec.rank);
144 145 146
            for(i=0; i<POSIX_NUM_INDICES; i++)
                DARSHAN_BSWAP64(&file->counters[i]);
            for(i=0; i<POSIX_F_NUM_INDICES; i++)
147 148 149 150 151 152 153 154
            {
                /* skip counters we explicitly set to -1 since they don't
                 * need to be byte swapped
                 */
                if((fd->mod_ver[DARSHAN_POSIX_MOD] < 3) &&
                    ((i == POSIX_F_CLOSE_START_TIMESTAMP) ||
                     (i == POSIX_F_OPEN_END_TIMESTAMP)))
                    continue;
155
                DARSHAN_BSWAP64(&file->fcounters[i]);
156
            }
157 158 159
        }

        return(1);
Shane Snyder's avatar
Shane Snyder committed
160
    }
161
}
Shane Snyder's avatar
Shane Snyder committed
162

163
static int darshan_log_put_posix_file(darshan_fd fd, void* posix_buf)
164 165 166 167
{
    struct darshan_posix_file *file = (struct darshan_posix_file *)posix_buf;
    int ret;

168
    ret = darshan_log_put_mod(fd, DARSHAN_POSIX_MOD, file,
169
        sizeof(struct darshan_posix_file), DARSHAN_POSIX_VER);
170 171
    if(ret < 0)
        return(-1);
172 173

    return(0);
Shane Snyder's avatar
Shane Snyder committed
174 175
}

176
static void darshan_log_print_posix_file(void *file_rec, char *file_name,
177
    char *mnt_pt, char *fs_type)
178 179 180 181 182 183 184 185
{
    int i;
    struct darshan_posix_file *posix_file_rec =
        (struct darshan_posix_file *)file_rec;

    for(i=0; i<POSIX_NUM_INDICES; i++)
    {
        DARSHAN_COUNTER_PRINT(darshan_module_names[DARSHAN_POSIX_MOD],
186 187 188
            posix_file_rec->base_rec.rank, posix_file_rec->base_rec.id,
            posix_counter_names[i], posix_file_rec->counters[i],
            file_name, mnt_pt, fs_type);
189 190 191 192 193
    }

    for(i=0; i<POSIX_F_NUM_INDICES; i++)
    {
        DARSHAN_F_COUNTER_PRINT(darshan_module_names[DARSHAN_POSIX_MOD],
194 195 196
            posix_file_rec->base_rec.rank, posix_file_rec->base_rec.id,
            posix_f_counter_names[i], posix_file_rec->fcounters[i],
            file_name, mnt_pt, fs_type);
197 198 199 200 201
    }

    return;
}

202
static void darshan_log_print_posix_description(int ver)
203
{
204
    printf("\n# description of POSIX counters:\n");
205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222
    printf("#   POSIX_*: posix operation counts.\n");
    printf("#   READS,WRITES,OPENS,SEEKS,STATS, and MMAPS are types of operations.\n");
    printf("#   POSIX_MODE: mode that file was opened in.\n");
    printf("#   POSIX_BYTES_*: total bytes read and written.\n");
    printf("#   POSIX_MAX_BYTE_*: highest offset byte read and written.\n");
    printf("#   POSIX_CONSEC_*: number of exactly adjacent reads and writes.\n");
    printf("#   POSIX_SEQ_*: number of reads and writes from increasing offsets.\n");
    printf("#   POSIX_RW_SWITCHES: number of times access alternated between read and write.\n");
    printf("#   POSIX_*_ALIGNMENT: memory and file alignment.\n");
    printf("#   POSIX_*_NOT_ALIGNED: number of reads and writes that were not aligned.\n");
    printf("#   POSIX_MAX_*_TIME_SIZE: size of the slowest read and write operations.\n");
    printf("#   POSIX_SIZE_*_*: histogram of read and write access sizes.\n");
    printf("#   POSIX_STRIDE*_STRIDE: the four most common strides detected.\n");
    printf("#   POSIX_STRIDE*_COUNT: count of the four most common strides.\n");
    printf("#   POSIX_ACCESS*_ACCESS: the four most common access sizes.\n");
    printf("#   POSIX_ACCESS*_COUNT: count of the four most common access sizes.\n");
    printf("#   POSIX_*_RANK: rank of the processes that were the fastest and slowest at I/O (for shared files).\n");
    printf("#   POSIX_*_RANK_BYTES: bytes transferred by the fastest and slowest ranks (for shared files).\n");
223 224
    printf("#   POSIX_F_*_START_TIMESTAMP: timestamp of first open/read/write/close.\n");
    printf("#   POSIX_F_*_END_TIMESTAMP: timestamp of last open/read/write/close.\n");
225 226 227 228 229
    printf("#   POSIX_F_READ/WRITE/META_TIME: cumulative time spent in read, write, or metadata operations.\n");
    printf("#   POSIX_F_MAX_*_TIME: duration of the slowest read and write operations.\n");
    printf("#   POSIX_F_*_RANK_TIME: fastest and slowest I/O time for a single rank (for shared files).\n");
    printf("#   POSIX_F_VARIANCE_RANK_*: variance of total I/O time and bytes moved for all ranks (for shared files).\n");

230 231 232 233 234 235 236 237 238 239 240 241 242 243
    if(ver <= 1)
    {
        printf("\n# WARNING: POSIX module log format version 1 has the following limitations:\n");
        printf("# - Partial instrumentation of stdio stream I/O functions not parsable by Darshan versions >= 3.1.0\n");
        printf("#     * Using darshan-logutils versions < 3.1.0, this data can be found in the following POSIX counters:\n");
        printf("#         * POSIX_FOPENS, POSIX_FREADS, POSIX_FWRITES, POSIX_FSEEKS\n");
    }
    if(ver <= 2)
    {
        printf("\n# WARNING: POSIX module log format version <=2 does not support the following counters:\n");
        printf("# - POSIX_F_CLOSE_START_TIMESTAMP\n");
        printf("# - POSIX_F_OPEN_END_TIMESTAMP\n");
    }

244 245 246
    return;
}

247 248 249 250 251 252 253 254 255 256 257 258 259 260 261
static void darshan_log_print_posix_file_diff(void *file_rec1, char *file_name1,
    void *file_rec2, char *file_name2)
{
    struct darshan_posix_file *file1 = (struct darshan_posix_file *)file_rec1;
    struct darshan_posix_file *file2 = (struct darshan_posix_file *)file_rec2;
    int i;

    /* NOTE: we assume that both input records are the same module format version */

    for(i=0; i<POSIX_NUM_INDICES; i++)
    {
        if(!file2)
        {
            printf("- ");
            DARSHAN_COUNTER_PRINT(darshan_module_names[DARSHAN_POSIX_MOD],
262
                file1->base_rec.rank, file1->base_rec.id, posix_counter_names[i],
263
                file1->counters[i], file_name1, "", "");
264

265 266 267 268 269
        }
        else if(!file1)
        {
            printf("+ ");
            DARSHAN_COUNTER_PRINT(darshan_module_names[DARSHAN_POSIX_MOD],
270
                file2->base_rec.rank, file2->base_rec.id, posix_counter_names[i],
271 272 273 274 275 276
                file2->counters[i], file_name2, "", "");
        }
        else if(file1->counters[i] != file2->counters[i])
        {
            printf("- ");
            DARSHAN_COUNTER_PRINT(darshan_module_names[DARSHAN_POSIX_MOD],
277
                file1->base_rec.rank, file1->base_rec.id, posix_counter_names[i],
278 279 280
                file1->counters[i], file_name1, "", "");
            printf("+ ");
            DARSHAN_COUNTER_PRINT(darshan_module_names[DARSHAN_POSIX_MOD],
281
                file2->base_rec.rank, file2->base_rec.id, posix_counter_names[i],
282 283 284 285 286 287 288 289 290 291
                file2->counters[i], file_name2, "", "");
        }
    }

    for(i=0; i<POSIX_F_NUM_INDICES; i++)
    {
        if(!file2)
        {
            printf("- ");
            DARSHAN_F_COUNTER_PRINT(darshan_module_names[DARSHAN_POSIX_MOD],
292
                file1->base_rec.rank, file1->base_rec.id, posix_f_counter_names[i],
293
                file1->fcounters[i], file_name1, "", "");
294

295 296 297 298 299
        }
        else if(!file1)
        {
            printf("+ ");
            DARSHAN_F_COUNTER_PRINT(darshan_module_names[DARSHAN_POSIX_MOD],
300
                file2->base_rec.rank, file2->base_rec.id, posix_f_counter_names[i],
301 302 303 304 305 306
                file2->fcounters[i], file_name2, "", "");
        }
        else if(file1->fcounters[i] != file2->fcounters[i])
        {
            printf("- ");
            DARSHAN_F_COUNTER_PRINT(darshan_module_names[DARSHAN_POSIX_MOD],
307
                file1->base_rec.rank, file1->base_rec.id, posix_f_counter_names[i],
308 309 310
                file1->fcounters[i], file_name1, "", "");
            printf("+ ");
            DARSHAN_F_COUNTER_PRINT(darshan_module_names[DARSHAN_POSIX_MOD],
311
                file2->base_rec.rank, file2->base_rec.id, posix_f_counter_names[i],
312 313 314 315 316 317 318
                file2->fcounters[i], file_name2, "", "");
        }
    }

    return;
}

319 320 321 322 323 324 325 326
/* simple helper struct for determining time & byte variances */
struct var_t
{
    double n;
    double M;
    double S;
};

327 328 329 330
static void darshan_log_agg_posix_files(void *rec, void *agg_rec, int init_flag)
{
    struct darshan_posix_file *psx_rec = (struct darshan_posix_file *)rec;
    struct darshan_posix_file *agg_psx_rec = (struct darshan_posix_file *)agg_rec;
331
    int i, j, k;
332 333 334 335
    int total_count;
    int64_t tmp_val[4];
    int64_t tmp_cnt[4];
    int tmp_ndx;
336
    double old_M;
337 338 339
    double psx_time = psx_rec->fcounters[POSIX_F_READ_TIME] +
        psx_rec->fcounters[POSIX_F_WRITE_TIME] +
        psx_rec->fcounters[POSIX_F_META_TIME];
340 341 342 343 344 345
    double psx_bytes = (double)psx_rec->counters[POSIX_BYTES_READ] +
        psx_rec->counters[POSIX_BYTES_WRITTEN];
    struct var_t *var_time_p = (struct var_t *)
        ((char *)rec + sizeof(struct darshan_posix_file));
    struct var_t *var_bytes_p = (struct var_t *)
        ((char *)var_time_p + sizeof(struct var_t));
346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386

    for(i = 0; i < POSIX_NUM_INDICES; i++)
    {
        switch(i)
        {
            case POSIX_OPENS:
            case POSIX_READS:
            case POSIX_WRITES:
            case POSIX_SEEKS:
            case POSIX_STATS:
            case POSIX_MMAPS:
            case POSIX_FSYNCS:
            case POSIX_FDSYNCS:
            case POSIX_BYTES_READ:
            case POSIX_BYTES_WRITTEN:
            case POSIX_CONSEC_READS:
            case POSIX_CONSEC_WRITES:
            case POSIX_SEQ_READS:
            case POSIX_SEQ_WRITES:
            case POSIX_RW_SWITCHES:
            case POSIX_MEM_NOT_ALIGNED:
            case POSIX_FILE_NOT_ALIGNED:
            case POSIX_SIZE_READ_0_100:
            case POSIX_SIZE_READ_100_1K:
            case POSIX_SIZE_READ_1K_10K:
            case POSIX_SIZE_READ_10K_100K:
            case POSIX_SIZE_READ_100K_1M:
            case POSIX_SIZE_READ_1M_4M:
            case POSIX_SIZE_READ_4M_10M:
            case POSIX_SIZE_READ_10M_100M:
            case POSIX_SIZE_READ_100M_1G:
            case POSIX_SIZE_READ_1G_PLUS:
            case POSIX_SIZE_WRITE_0_100:
            case POSIX_SIZE_WRITE_100_1K:
            case POSIX_SIZE_WRITE_1K_10K:
            case POSIX_SIZE_WRITE_10K_100K:
            case POSIX_SIZE_WRITE_100K_1M:
            case POSIX_SIZE_WRITE_1M_4M:
            case POSIX_SIZE_WRITE_4M_10M:
            case POSIX_SIZE_WRITE_10M_100M:
            case POSIX_SIZE_WRITE_100M_1G:
387
            case POSIX_SIZE_WRITE_1G_PLUS:
388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412
                /* sum */
                agg_psx_rec->counters[i] += psx_rec->counters[i];
                break;
            case POSIX_MODE:
            case POSIX_MEM_ALIGNMENT:
            case POSIX_FILE_ALIGNMENT:
                /* just set to the input value */
                agg_psx_rec->counters[i] = psx_rec->counters[i];
                break;
            case POSIX_MAX_BYTE_READ:
            case POSIX_MAX_BYTE_WRITTEN:
                /* max */
                if(psx_rec->counters[i] > agg_psx_rec->counters[i])
                {
                    agg_psx_rec->counters[i] = psx_rec->counters[i];
                }
                break;
            case POSIX_MAX_READ_TIME_SIZE:
            case POSIX_MAX_WRITE_TIME_SIZE:
            case POSIX_FASTEST_RANK:
            case POSIX_FASTEST_RANK_BYTES:
            case POSIX_SLOWEST_RANK:
            case POSIX_SLOWEST_RANK_BYTES:
                /* these are set with the FP counters */
                break;
413 414 415
            case POSIX_STRIDE1_STRIDE:
            case POSIX_ACCESS1_ACCESS:
                /* increment common value counters */
416 417

                /* first, collapse duplicates */
418 419 420 421 422 423 424
                for(j = i; j < i + 4; j++)
                {
                    for(k = 0; k < 4; k++)
                    {
                        if(agg_psx_rec->counters[i + k] == psx_rec->counters[j])
                        {
                            agg_psx_rec->counters[i + k + 4] += psx_rec->counters[j + 4];
425 426 427 428 429 430 431 432 433 434 435 436
                            psx_rec->counters[j] = psx_rec->counters[j + 4] = 0;
                        }
                    }
                }

                /* second, add new counters */
                for(j = i; j < i + 4; j++)
                {
                    tmp_ndx = 0;
                    memset(tmp_val, 0, 4 * sizeof(int64_t));
                    memset(tmp_cnt, 0, 4 * sizeof(int64_t));

437
                    if(psx_rec->counters[j] == 0) break;
438 439 440 441 442 443
                    for(k = 0; k < 4; k++)
                    {
                        if(agg_psx_rec->counters[i + k] == psx_rec->counters[j])
                        {
                            total_count = agg_psx_rec->counters[i + k + 4] +
                                psx_rec->counters[j + 4];
444 445
                            break;
                        }
446 447 448 449 450 451 452 453
                    }
                    if(k == 4) total_count = psx_rec->counters[j + 4];

                    for(k = 0; k < 4; k++)
                    {
                        if((agg_psx_rec->counters[i + k + 4] > total_count) ||
                           ((agg_psx_rec->counters[i + k + 4] == total_count) &&
                            (agg_psx_rec->counters[i + k] > psx_rec->counters[j])))
454
                        {
455 456 457
                            tmp_val[tmp_ndx] = agg_psx_rec->counters[i + k];
                            tmp_cnt[tmp_ndx] = agg_psx_rec->counters[i + k + 4];
                            tmp_ndx++;
458
                        }
459
                        else break;
460
                    }
461 462 463 464 465 466 467
                    if(tmp_ndx == 4) break;

                    tmp_val[tmp_ndx] = psx_rec->counters[j];
                    tmp_cnt[tmp_ndx] = psx_rec->counters[j + 4];
                    tmp_ndx++;

                    while(tmp_ndx != 4)
468
                    {
469 470 471 472 473 474 475
                        if(agg_psx_rec->counters[i + k] != psx_rec->counters[j])
                        {
                            tmp_val[tmp_ndx] = agg_psx_rec->counters[i + k];
                            tmp_cnt[tmp_ndx] = agg_psx_rec->counters[i + k + 4];
                            tmp_ndx++;
                        }
                        k++;
476
                    }
477 478
                    memcpy(&(agg_psx_rec->counters[i]), tmp_val, 4 * sizeof(int64_t));
                    memcpy(&(agg_psx_rec->counters[i + 4]), tmp_cnt, 4 * sizeof(int64_t));
479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496
                }
                break;
            case POSIX_STRIDE2_STRIDE:
            case POSIX_STRIDE3_STRIDE:
            case POSIX_STRIDE4_STRIDE:
            case POSIX_STRIDE1_COUNT:
            case POSIX_STRIDE2_COUNT:
            case POSIX_STRIDE3_COUNT:
            case POSIX_STRIDE4_COUNT:
            case POSIX_ACCESS2_ACCESS:
            case POSIX_ACCESS3_ACCESS:
            case POSIX_ACCESS4_ACCESS:
            case POSIX_ACCESS1_COUNT:
            case POSIX_ACCESS2_COUNT:
            case POSIX_ACCESS3_COUNT:
            case POSIX_ACCESS4_COUNT:
                /* these are set all at once with common counters above */
                break;
497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512
            default:
                agg_psx_rec->counters[i] = -1;
                break;
        }
    }

    for(i = 0; i < POSIX_F_NUM_INDICES; i++)
    {
        switch(i)
        {
            case POSIX_F_READ_TIME:
            case POSIX_F_WRITE_TIME:
            case POSIX_F_META_TIME:
                /* sum */
                agg_psx_rec->fcounters[i] += psx_rec->fcounters[i];
                break;
513
            case POSIX_F_OPEN_START_TIMESTAMP:
514 515
            case POSIX_F_READ_START_TIMESTAMP:
            case POSIX_F_WRITE_START_TIMESTAMP:
516
            case POSIX_F_CLOSE_START_TIMESTAMP:
517 518 519 520
                /* minimum non-zero */
                if((psx_rec->fcounters[i] > 0)  &&
                    ((agg_psx_rec->fcounters[i] == 0) ||
                    (psx_rec->fcounters[i] < agg_psx_rec->fcounters[i])))
521 522 523 524
                {
                    agg_psx_rec->fcounters[i] = psx_rec->fcounters[i];
                }
                break;
525
            case POSIX_F_OPEN_END_TIMESTAMP:
526 527
            case POSIX_F_READ_END_TIMESTAMP:
            case POSIX_F_WRITE_END_TIMESTAMP:
528
            case POSIX_F_CLOSE_END_TIMESTAMP:
529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551
                /* maximum */
                if(psx_rec->fcounters[i] > agg_psx_rec->fcounters[i])
                {
                    agg_psx_rec->fcounters[i] = psx_rec->fcounters[i];
                }
                break;
            case POSIX_F_MAX_READ_TIME:
                if(psx_rec->fcounters[i] > agg_psx_rec->fcounters[i])
                {
                    agg_psx_rec->fcounters[i] = psx_rec->fcounters[i];
                    agg_psx_rec->counters[POSIX_MAX_READ_TIME_SIZE] =
                        psx_rec->counters[POSIX_MAX_READ_TIME_SIZE];
                }
                break;
            case POSIX_F_MAX_WRITE_TIME:
                if(psx_rec->fcounters[i] > agg_psx_rec->fcounters[i])
                {
                    agg_psx_rec->fcounters[i] = psx_rec->fcounters[i];
                    agg_psx_rec->counters[POSIX_MAX_WRITE_TIME_SIZE] =
                        psx_rec->counters[POSIX_MAX_WRITE_TIME_SIZE];
                }
                break;
            case POSIX_F_FASTEST_RANK_TIME:
552 553 554 555 556 557 558 559 560 561
                if(init_flag)
                {
                    /* set fastest rank counters according to root rank. these counters
                     * will be determined as the aggregation progresses.
                     */
                    agg_psx_rec->counters[POSIX_FASTEST_RANK] = psx_rec->base_rec.rank;
                    agg_psx_rec->counters[POSIX_FASTEST_RANK_BYTES] = psx_bytes;
                    agg_psx_rec->fcounters[POSIX_F_FASTEST_RANK_TIME] = psx_time;
                }

562 563 564
                if(psx_time < agg_psx_rec->fcounters[POSIX_F_FASTEST_RANK_TIME])
                {
                    agg_psx_rec->counters[POSIX_FASTEST_RANK] = psx_rec->base_rec.rank;
565
                    agg_psx_rec->counters[POSIX_FASTEST_RANK_BYTES] = psx_bytes;
566 567 568 569
                    agg_psx_rec->fcounters[POSIX_F_FASTEST_RANK_TIME] = psx_time;
                }
                break;
            case POSIX_F_SLOWEST_RANK_TIME:
570 571 572 573 574 575 576 577 578 579
                if(init_flag)
                {
                    /* set slowest rank counters according to root rank. these counters
                     * will be determined as the aggregation progresses.
                     */
                    agg_psx_rec->counters[POSIX_SLOWEST_RANK] = psx_rec->base_rec.rank;
                    agg_psx_rec->counters[POSIX_SLOWEST_RANK_BYTES] = psx_bytes;
                    agg_psx_rec->fcounters[POSIX_F_SLOWEST_RANK_TIME] = psx_time;
                }

580 581 582
                if(psx_time > agg_psx_rec->fcounters[POSIX_F_SLOWEST_RANK_TIME])
                {
                    agg_psx_rec->counters[POSIX_SLOWEST_RANK] = psx_rec->base_rec.rank;
583
                    agg_psx_rec->counters[POSIX_SLOWEST_RANK_BYTES] = psx_bytes;
584 585 586
                    agg_psx_rec->fcounters[POSIX_F_SLOWEST_RANK_TIME] = psx_time;
                }
                break;
587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624
            case POSIX_F_VARIANCE_RANK_TIME:
                if(init_flag)
                {
                    var_time_p->n = 1;
                    var_time_p->M = psx_time;
                    var_time_p->S = 0;
                }
                else
                {
                    old_M = var_time_p->M;

                    var_time_p->n++;
                    var_time_p->M += (psx_time - var_time_p->M) / var_time_p->n;
                    var_time_p->S += (psx_time - var_time_p->M) * (psx_time - old_M);

                    agg_psx_rec->fcounters[POSIX_F_VARIANCE_RANK_TIME] =
                        var_time_p->S / var_time_p->n;
                }
                break;
            case POSIX_F_VARIANCE_RANK_BYTES:
                if(init_flag)
                {
                    var_bytes_p->n = 1;
                    var_bytes_p->M = psx_bytes;
                    var_bytes_p->S = 0;
                }
                else
                {
                    old_M = var_bytes_p->M;

                    var_bytes_p->n++;
                    var_bytes_p->M += (psx_bytes - var_bytes_p->M) / var_bytes_p->n;
                    var_bytes_p->S += (psx_bytes - var_bytes_p->M) * (psx_bytes - old_M);

                    agg_psx_rec->fcounters[POSIX_F_VARIANCE_RANK_BYTES] =
                        var_bytes_p->S / var_bytes_p->n;
                }
                break;
625 626 627 628 629 630 631 632 633
            default:
                agg_psx_rec->fcounters[i] = -1;
                break;
        }
    }

    return;
}

Shane Snyder's avatar
Shane Snyder committed
634 635 636 637 638 639 640 641
/*
 * Local variables:
 *  c-indent-level: 4
 *  c-basic-offset: 4
 * End:
 *
 * vim: ts=8 sts=4 sw=4 expandtab
 */