1/**
2 * \file
3 * \brief Simple Barrier test
4 */
5
6/*
7 * Copyright (c) 2011, ETH Zurich.
8 * All rights reserved.
9 *
10 * This file is distributed under the terms in the attached LICENSE file.
11 * If you do not find this file, copies can be found by writing to:
12 * ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
13 */
14
15#include <stdlib.h>
16#include <stdio.h>
17#include <assert.h>
18
19#include <barrelfish/barrelfish.h>
20#include <bench/bench.h>
21#include <octopus/octopus.h>
22#include <skb/skb.h>
23
24#include <if/octopus_thc.h>
25
26#define MAX_ITERATIONS 500
27struct timestamp {
28    cycles_t time0;
29    cycles_t time1;
30    cycles_t server;
31    uint8_t busy;
32};
33struct timestamp timestamps[MAX_ITERATIONS] = { { 0, 0, 0, 0 } };
34//static size_t records[] = { 0, 8, 16, 256, 512, 768, 1000, 1500, 2000, 2500,
35//        4000, 5000, 6000, 7000, 8000, 9000, 10000, 12000, 20000 };
36
37static size_t records[] = { 0, 1, 50000, 100000, 150000, 200000, 400000, 600000, 800000, 1000000, 1200000,
381400000 };
39
40static size_t add_records[] = { 0, 1, 50000, 100000, 150000, 200000, 400000, 600000, 800000, 1000000, 1200000,
411400000 };
42
43static void variable_records(void)
44{
45    size_t exps = sizeof(records) / sizeof(size_t);
46    for (size_t i = 1; i < exps; i++) {
47        printf("# Run experiment with %zu records:\n", records[i]);
48
49        for (size_t j = records[i - 1]; j < records[i]; j++) {
50            errval_t err = oct_set("object%zu { attr: 'object%zu' }", j, j);
51            if (err_is_fail(err)) {
52                DEBUG_ERR(err, "set");
53                exit(0);
54            }
55        }
56
57        errval_t error_code;
58        char* data = NULL;
59
60        struct octopus_thc_client_binding_t* cl = oct_get_thc_client();
61        assert(cl != NULL);
62        octopus_trigger_id_t tid;
63
64
65        for (size_t k = 0; k < MAX_ITERATIONS; k++) {
66            size_t get_nr = bench_tsc() % records[i];
67            char buf[100];
68            sprintf(buf, "object%zu", get_nr);
69
70            timestamps[k].time0 = bench_tsc();
71            cl->call_seq.get(cl, buf, NOP_TRIGGER, &data, &tid, &error_code);
72            timestamps[k].time1 = bench_tsc();
73            if (err_is_fail(error_code)) {
74                DEBUG_ERR(error_code, "get");
75                exit(0);
76            }
77            free(data);
78        }
79
80        for (size_t k = 0; k < MAX_ITERATIONS; k++) {
81            printf(
82                    "%zu %"PRIuCYCLES" %"PRIuCYCLES" %d %zu\n",
83                    k,
84                    timestamps[k].time1 - timestamps[k].time0
85                            - bench_tscoverhead(), timestamps[k].server,
86                    timestamps[k].busy, records[i]);
87        }
88
89    }
90}
91
92static void add_record(void) {
93    size_t exps = sizeof(add_records) / sizeof(size_t);
94    struct octopus_thc_client_binding_t* cl = oct_get_thc_client();
95    assert(cl != NULL);
96
97    errval_t error_code;
98    char* ret = NULL;
99    char* record = "rec_ { attribute: 1 }";
100    octopus_trigger_id_t tid;
101
102    for (size_t i = 1; i < exps; i++) {
103        printf("# Run add_record with %zu records:\n", add_records[i]);
104
105        for (size_t j = add_records[i - 1]; j < add_records[i]; j++) {
106            //printf("add to system: %s\n", record);
107            cl->call_seq.set(cl, record, SET_SEQUENTIAL, NOP_TRIGGER, false, &ret, &tid, &error_code);
108            assert(ret == NULL);
109            if(err_is_fail(error_code)) { DEBUG_ERR(error_code, "add"); exit(0); }
110        }
111
112        char to_add[100];
113        sprintf(to_add, "zzz { attribute: 1 }");
114        char* data;
115        for (size_t k = 0; k < MAX_ITERATIONS; k++) {
116            timestamps[k].time0 = bench_tsc();
117            cl->call_seq.set(cl, to_add, SET_DEFAULT, NOP_TRIGGER, false, &data, &tid, &error_code);
118            timestamps[k].time1 = bench_tsc();
119            if (err_is_fail(error_code)) {
120                DEBUG_ERR(error_code, "set");
121                exit(0);
122            }
123            free(data);
124
125            cl->call_seq.del(cl, to_add, NOP_TRIGGER, &tid, &error_code);
126            if (err_is_fail(error_code)) {
127                DEBUG_ERR(error_code, "del");
128                exit(0);
129            }
130            if (timestamps[k].busy == 1) k--; // ignore the ones that were busy on send
131        }
132
133        for (size_t k = 0; k < MAX_ITERATIONS; k++) {
134            printf(
135                    "%zu %"PRIuCYCLES" %"PRIuCYCLES" %d %zu\n",
136                    k,
137                    timestamps[k].time1 - timestamps[k].time0
138                    - bench_tscoverhead(), timestamps[k].server,
139                    timestamps[k].busy, add_records[i]);
140        }
141    }
142
143}
144
145static void one_record(void)
146{
147    errval_t err = oct_set("object0");
148    assert(err_is_ok(err));
149
150    errval_t error_code;
151    char* data = NULL;
152
153    struct octopus_thc_client_binding_t* cl = oct_get_thc_client();
154    octopus_trigger_id_t tid;
155
156    for (size_t i = 0; i < MAX_ITERATIONS; i++) {
157
158        timestamps[i].time0 = bench_tsc();
159        cl->call_seq.get(cl, "object0", NOP_TRIGGER, &data, &tid, &error_code);
160        timestamps[i].time1 = bench_tsc();
161
162        assert(err_is_ok(error_code));
163        free(data);
164        for(size_t j=0; j<1<<20; j++) {}
165    }
166
167    for (size_t i = 0; i < MAX_ITERATIONS; i++) {
168        printf("%zu %"PRIuCYCLES" %"PRIuCYCLES" %d\n", i,
169                timestamps[i].time1 - timestamps[i].time0 - bench_tscoverhead(),
170                timestamps[i].server, timestamps[i].busy);
171    }
172}
173
174static void unnamed_record(void)
175{
176    errval_t err = oct_set("object0 { attr1: 'bla', attr2: 12.0 }");
177    assert(err_is_ok(err));
178
179    octopus_trigger_id_t tid;
180
181    struct octopus_thc_client_binding_t* cl = oct_get_thc_client();
182    assert(cl != NULL);
183
184    char* data = NULL;
185    errval_t error_code;
186    for (size_t i = 0; i < MAX_ITERATIONS; i++) {
187
188        timestamps[i].time0 = bench_tsc();
189        cl->call_seq.get(cl, "_ { attr1: 'bla', attr2: 12.0 }", NOP_TRIGGER, &data, &tid, &error_code);
190        timestamps[i].time1 = bench_tsc();
191
192        assert(err_is_ok(error_code));
193        free(data);
194
195        for(size_t j=0; j<1<<20; j++) {}
196    }
197
198    for (size_t i = 0; i < MAX_ITERATIONS; i++) {
199        printf("%zu %"PRIuCYCLES" %"PRIuCYCLES" %d\n", i,
200                timestamps[i].time1 - timestamps[i].time0 - bench_tscoverhead(),
201                timestamps[i].server, timestamps[i].busy);
202    }
203}
204
205int main(int argc, char** argv)
206{
207    bench_init();
208    oct_init();
209
210    if (0) one_record();
211    if (0) variable_records();
212    if (0) add_record();
213    if (0) unnamed_record();
214
215    /*
216    debug_printf("1000000000 cycles in ms: %lu\n", bench_tsc_to_ms(1000000000));
217    debug_printf(" 100000000 cycles in ms: %lu\n", bench_tsc_to_ms( 100000000));
218    debug_printf("  10000000 cycles in ms: %lu\n", bench_tsc_to_ms(  10000000));
219    debug_printf("   3333333 cycles in ms: %lu\n", bench_tsc_to_ms(   3333333));
220    debug_printf("   2800000 cycles in ms: %lu\n", bench_tsc_to_ms(   2800000));
221    debug_printf("   2700000 cycles in ms: %lu\n", bench_tsc_to_ms(   2700000));*/
222
223}
224