test-workload-method.c 3.77 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
#include "ross.h"
#include "codes/codes-workload.h"
16
#include "src/workload/codes-workload-method.h"
17

Philip Carns's avatar
Philip Carns committed
18 19
static int test_workload_load(const char* params, int rank);
static void test_workload_get_next(int rank, struct codes_workload_op *op);
20

21 22 23 24 25 26 27 28 29 30 31 32
/* 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
33
/* fill in function pointers for this method */
34 35 36 37 38 39 40
struct codes_workload_method test_workload_method = 
{
    .method_name = "test",
    .codes_workload_load = test_workload_load,
    .codes_workload_get_next = test_workload_get_next,
};

Philip Carns's avatar
Philip Carns committed
41
static int test_workload_load(const char* params, int rank)
42 43 44 45
{
    /* no params in this case; this example will work with any number of
     * ranks
     */
46 47 48 49 50 51 52 53
    struct wkload_stream_state* new;

    new = malloc(sizeof(*new));
    if(!new)
        return(-1);

    new->rank = rank;

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

    /* add to front of list of streams that we are tracking */
    new->next = wkload_streams;
    wkload_streams = new;

87
    return(0);
88 89
}

Philip Carns's avatar
Philip Carns committed
90 91
/* find the next workload operation to issue for this rank */
static void test_workload_get_next(int rank, struct codes_workload_op *op)
92
{
93 94 95 96 97 98 99 100 101 102 103
    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
104 105 106 107 108 109
    if(!tmp)
    {
        op->op_type = CODES_WK_END;
        return;
    }

110 111 112 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
    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);
    }
142 143 144 145 146 147 148 149 150 151 152 153

    return;
}

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