test-workload-method.c 3.87 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;

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
     */
46
    struct wkload_stream_state* newv;
47

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

52
    newv->rank = rank;
53

54
    /* arbitrary synthetic workload for testing purposes */
55 56 57 58 59
    /* rank 0 sleeps 43 seconds, then does open and barrier, while all other
     * ranks immediately do open and barrier
     */
    if(rank == 0)
    {
60 61 62 63 64 65 66 67 68 69
        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 */
70 71 72
    }
    else
    {
73 74 75 76 77 78 79 80
        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 */
81
    }
82 83

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

87
    return(0);
88 89
}

90
/* find the next workload operation to issue for this rank */
91
static void test_workload_get_next(int app_id, 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;
    }

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
 */