test-workload-method.c 3.92 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11
/*
 * Copyright (C) 2013 University of Chicago.
 * See COPYRIGHT notice in top-level directory.
 *
 */

/* Example of a workload generator that plugs into the codes workload
 * generator API.  This example just produces a hard-coded pattern for
 * testing/validation purposes.
 */

12 13
#include <assert.h>

14 15 16
#include "ross.h"
#include "codes/codes-workload.h"

17 18
static int test_workload_load(const char* params, int app_id, int rank);
static void test_workload_get_next(int app_id, int rank, struct codes_workload_op *op);
19

20 21 22 23 24 25 26 27 28 29 30 31
/* state information for each rank that is retrieving requests */
struct wkload_stream_state
{
    int rank;
    struct wkload_stream_state* next;
    struct codes_workload_op op_array[16];
    int op_array_len;
    int op_array_index;
};

struct wkload_stream_state* wkload_streams = NULL;

Philip Carns's avatar
Philip Carns committed
32
/* fill in function pointers for this method */
33 34 35
struct codes_workload_method test_workload_method = 
{
    .method_name = "test",
36
    .codes_workload_read_config = NULL,
37 38 39 40
    .codes_workload_load = test_workload_load,
    .codes_workload_get_next = test_workload_get_next,
};

41
static int test_workload_load(const char* params, int app_id, int rank)
42 43 44 45
{
    /* no params in this case; this example will work with any number of
     * ranks
     */
Jonathan Jenkins's avatar
Jonathan Jenkins committed
46 47
    (void)params;
    (void)app_id;
48
    struct wkload_stream_state* newv;
49

50
    newv = (struct wkload_stream_state*)malloc(sizeof(*newv));
51
    if(!newv)
52 53
        return(-1);

54
    newv->rank = rank;
55

Philip Carns's avatar
Philip Carns committed
56
    /* arbitrary synthetic workload for testing purposes */
Philip Carns's avatar
Philip Carns committed
57 58 59 60 61
    /* rank 0 sleeps 43 seconds, then does open and barrier, while all other
     * ranks immediately do open and barrier
     */
    if(rank == 0)
    {
62 63 64 65 66 67 68 69 70 71
        newv->op_array_len = 3;
        newv->op_array_index = 0;
        newv->op_array[0].op_type = CODES_WK_DELAY;
        newv->op_array[0].u.delay.seconds = 43;
        newv->op_array[1].op_type = CODES_WK_OPEN;
        newv->op_array[1].u.open.file_id = 3;
        newv->op_array[1].u.open.create_flag = 1;
        newv->op_array[2].op_type = CODES_WK_BARRIER;
        newv->op_array[2].u.barrier.root = 0;
        newv->op_array[2].u.barrier.count = -1; /* all ranks */
Philip Carns's avatar
Philip Carns committed
72 73 74
    }
    else
    {
75 76 77 78 79 80 81 82
        newv->op_array_len = 2;
        newv->op_array_index = 0;
        newv->op_array[0].op_type = CODES_WK_OPEN;
        newv->op_array[0].u.open.file_id = 3;
        newv->op_array[0].u.open.create_flag = 1;
        newv->op_array[1].op_type = CODES_WK_BARRIER;
        newv->op_array[1].u.barrier.root = 0;
        newv->op_array[1].u.barrier.count = -1; /* all ranks */
Philip Carns's avatar
Philip Carns committed
83
    }
84 85

    /* add to front of list of streams that we are tracking */
86 87
    newv->next = wkload_streams;
    wkload_streams = newv;
88

89
    return(0);
90 91
}

Philip Carns's avatar
Philip Carns committed
92
/* find the next workload operation to issue for this rank */
93
static void test_workload_get_next(int app_id, int rank, struct codes_workload_op *op)
94
{
Jonathan Jenkins's avatar
Jonathan Jenkins committed
95
    (void)app_id;
96 97 98 99 100 101 102 103 104 105 106
    struct wkload_stream_state* tmp = wkload_streams;
    struct wkload_stream_state* tmp2 = wkload_streams;

    /* find stream associated with this rank */
    while(tmp)
    {
        if(tmp->rank == rank)
            break;
        tmp = tmp->next;
    }

Philip Carns's avatar
Philip Carns committed
107 108 109 110 111 112
    if(!tmp)
    {
        op->op_type = CODES_WK_END;
        return;
    }

113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
    assert(tmp->rank == rank);

    if(tmp->op_array_index < tmp->op_array_len)
    {
        *op = tmp->op_array[tmp->op_array_index];
        tmp->op_array_index++;
    }
    else
    {
        /* no more operations */
        op->op_type = CODES_WK_END;

        /* destroy this instance */
        if(wkload_streams == tmp)
        {
            wkload_streams = tmp->next;
        }
        else
        {
            while(tmp2)
            {
                if(tmp2->next == tmp)
                {
                    tmp2->next = tmp->next;
                    break;
                }
                tmp2 = tmp2->next;
            }
        }

        free(tmp);
    }
145 146 147 148 149 150 151 152 153 154 155 156

    return;
}

/*
 * Local variables:
 *  c-indent-level: 4
 *  c-basic-offset: 4
 * End:
 *
 * vim: ft=c ts=8 sts=4 sw=4 expandtab
 */