1/**
2 * \file
3 * \brief Flounder stubs
4 */
5
6/*
7 * Copyright (c) 2007, 2008, 2009, 2010, 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 <stdio.h>
16#include <barrelfish/barrelfish.h>
17#include <string.h>
18#include <barrelfish/nameservice_client.h>
19#include <barrelfish/spawn_client.h>
20#include <bench/bench.h>
21#include <if/glue_bench_types.h>
22
23static char my_name[100];
24
25static struct glue_bench_service_response *binding;
26static coreid_t my_core_id;
27
28#define MAX_COUNT 1000
29
30struct timestamp {
31    cycles_t time0;
32    cycles_t time1;
33};
34static struct timestamp timestamps[MAX_COUNT];
35static int benchmark_type = 0;
36
37static void experiment(void)
38{
39    errval_t err;
40    static bool flag = false;
41    static int i = 0;
42
43    // Experiment finished
44    if (i == MAX_COUNT - 1) {
45        timestamps[i].time1 = bench_tsc();
46
47        for (int j = MAX_COUNT / 10; j < MAX_COUNT; j++) {
48            printf("page %d took %"PRIuCYCLES"\n", j,
49                   timestamps[j].time1 - bench_tscoverhead() -
50                   timestamps[j].time0);
51        }
52
53        printf("client done\n");
54        return;
55    }
56
57    if (!flag) { // Start experiment
58        timestamps[i].time0 = bench_tsc();
59        flag = true;
60    } else { // Continue experiment
61        timestamps[i].time1 = bench_tsc();
62        timestamps[i+1].time0 = timestamps[i].time1;
63        i++;
64    }
65
66    assert(binding);
67    assert(binding->f);
68
69    switch(benchmark_type) {
70    case 0:
71        assert(binding->f->fsb_payload_request);
72        err = binding->f->fsb_payload_request(binding, 1, 2, 3, 4);
73        break;
74
75    case 1:
76        assert(binding->f->fsb_empty_request);
77        err = binding->f->fsb_empty_request(binding);
78        break;
79
80    case 2:
81        assert(binding->f->fsb_payload1_request);
82        err = binding->f->fsb_payload1_request(binding, 1);
83        break;
84
85    case 3:
86        assert(binding->f->fsb_payload2_request);
87        err = binding->f->fsb_payload2_request(binding, 1, 2);
88        break;
89
90    case 4:
91        assert(binding->f->fsb_payload8_request);
92        err = binding->f->fsb_payload8_request(binding, 1, 2, 3, 4, 5, 6, 7, 8);
93        break;
94
95    case 5:
96        assert(binding->f->fsb_payload16_request);
97        err = binding->f->fsb_payload16_request(binding, 1, 2, 3, 4, 5, 6, 7, 8,
98                                                9, 10, 11, 12, 13, 14, 15, 16);
99        break;
100
101    default:
102        printf("unknown benchmark type\n");
103        abort();
104        break;
105    }
106
107    assert(err_is_ok(err));
108}
109
110static void fsb_init_msg(struct glue_bench_service_response *b, coreid_t id)
111{
112    binding = b;
113    printf("Running flounder_stubs_payload between core %d and core %d\n", my_core_id, 1);
114    experiment();
115}
116
117static void fsb_payload_reply(struct glue_bench_service_response *b,
118                              int payload0, int payload1,
119                              int payload2, int payload3)
120{
121    experiment();
122}
123
124static void fsb_empty_reply(struct glue_bench_service_response *b)
125{
126    experiment();
127}
128
129static void fsb_payload1_reply(struct glue_bench_service_response *b,
130                               int p0)
131{
132    experiment();
133}
134
135static void fsb_payload2_reply(struct glue_bench_service_response *b,
136                               int p0, int p1)
137{
138    experiment();
139}
140
141static void fsb_payload8_reply(struct glue_bench_service_response *b,
142                               int p0, int p1, int p2, int p3,
143                               int p4, int p5, int p6, int p7)
144{
145    experiment();
146}
147
148static void fsb_payload16_reply(struct glue_bench_service_response *b,
149                                int p0, int p1, int p2, int p3,
150                                int p4, int p5, int p6, int p7,
151                                int p8, int p9, int p10, int p11,
152                                int p12, int p13, int p14, int p15)
153{
154    experiment();
155}
156
157static void listen_cb(struct glue_bench_service *closure, iref_t iref)
158{
159    /* if iref == 0, listen failed */
160    assert(iref != 0);
161
162    errval_t err = nameservice_register("server", iref);
163    if (err_is_fail(err)) {
164        DEBUG_ERR(err, "nameservice_register failed");
165        abort();
166    }
167}
168
169static struct glue_bench_server_call_vtbl call_vtbl = {
170    .fsb_init_msg   = fsb_init_msg,
171    .fsb_payload_reply = fsb_payload_reply,
172    .fsb_empty_reply = fsb_empty_reply,
173    .fsb_payload1_reply = fsb_payload1_reply,
174    .fsb_payload2_reply = fsb_payload2_reply,
175    .fsb_payload8_reply = fsb_payload8_reply,
176    .fsb_payload16_reply = fsb_payload16_reply,
177    ._listening = listen_cb,
178    ._connected = NULL,
179};
180
181static struct glue_bench_service service = {
182    .f = &call_vtbl,
183};
184
185static void fsb_payload_request(struct glue_bench_client_response *b,
186                              int payload0, int payload1,
187                              int payload2, int payload3)
188{
189    errval_t err;
190    err = b->call_vtbl->fsb_payload_reply(b, 1, 2, 3, 4);
191    assert(err_is_ok(err));
192}
193
194static void fsb_empty_request(struct glue_bench_client_response *b)
195{
196    errval_t err;
197    err = b->call_vtbl->fsb_empty_reply(b);
198    assert(err_is_ok(err));
199}
200
201static void fsb_payload1_request(struct glue_bench_client_response *b,
202                              int payload0)
203{
204    errval_t err;
205    err = b->call_vtbl->fsb_payload1_reply(b, 1);
206    assert(err_is_ok(err));
207}
208
209static void fsb_payload2_request(struct glue_bench_client_response *b,
210                                 int payload0, int payload1)
211{
212    errval_t err;
213    err = b->call_vtbl->fsb_payload2_reply(b, 1, 2);
214    assert(err_is_ok(err));
215}
216
217static void fsb_payload8_request(struct glue_bench_client_response *b,
218                                 int payload0, int payload1,
219                                 int payload2, int payload3,
220                                 int payload4, int payload5,
221                                 int payload6, int payload7)
222{
223    errval_t err;
224    err = b->call_vtbl->fsb_payload8_reply(b, 1, 2, 3, 4, 5, 6, 7, 8);
225    assert(err_is_ok(err));
226}
227
228static void fsb_payload16_request(struct glue_bench_client_response *b,
229                                  int payload0, int payload1,
230                                  int payload2, int payload3,
231                                  int payload4, int payload5,
232                                  int payload6, int payload7,
233                                  int payload8, int payload9,
234                                  int payload10, int payload11,
235                                  int payload12, int payload13,
236                                  int payload14, int payload15)
237{
238    errval_t err;
239    err = b->call_vtbl->fsb_payload16_reply(b, 1, 2, 3, 4, 5, 6, 7, 8,
240                                            9, 10, 11, 12, 13, 14, 15, 16);
241    assert(err_is_ok(err));
242}
243
244static void client_connect_cb(struct glue_bench_client_response *b)
245{
246    errval_t err;
247    err = b->call_vtbl->fsb_init_msg(b, my_core_id);
248    assert(err_is_ok(err));
249}
250
251int main(int argc, char *argv[])
252{
253    errval_t err;
254
255    /* Set my core id */
256    my_core_id = disp_get_core_id();
257    strcpy(my_name, argv[0]);
258
259    bench_init();
260
261    // Default first arg
262    if(argc == 1) {
263        argc = 2;
264        argv[1] = "0";
265    }
266
267    if (argc == 2) { /* bsp core */
268        benchmark_type = atoi(argv[1]);
269
270        /*
271          1. spawn domain,
272          2. setup a server,
273          3. wait for client to connect,
274          4. run experiment
275        */
276        char *xargv[] = {my_name, "dummy", "dummy", NULL};
277        err = spawn_program(1, my_name, xargv, NULL,
278                            SPAWN_FLAGS_DEFAULT, NULL);
279        assert(err_is_ok(err));
280
281        /* Setup a server */
282        errval_t r = glue_bench_listen(&service);
283        assert(err_is_ok(r));
284    } else {
285        /* Connect to the server */
286        iref_t iref;
287
288        err = nameservice_blocking_lookup("server", &iref);
289        if (err_is_fail(err)) {
290            return err; // XXX
291        }
292
293        assert(iref != 0);
294
295        static struct glue_bench_client_response_vtbl crv = {
296            .fsb_payload_request = fsb_payload_request,
297            .fsb_empty_request = fsb_empty_request,
298            .fsb_payload1_request = fsb_payload1_request,
299            .fsb_payload2_request = fsb_payload2_request,
300            .fsb_payload8_request = fsb_payload8_request,
301            .fsb_payload16_request = fsb_payload16_request,
302            ._connected = client_connect_cb,
303        };
304        static struct glue_bench_client_response client;
305        client.f = &crv;
306        glue_bench_connect(iref, &client, 0);
307    }
308
309    messages_handler_loop();
310}
311