1/**
2 * \file
3 * \brief
4 */
5
6/*
7 * Copyright (c) 2010, ETH Zurich and Mircosoft Corporation.
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 "internal.h"
16
17struct timestamp *timestamp;
18static callback retcb;
19static coreset_token_t token;
20static coreid_t id;
21static int counter;
22
23void ping(struct boot_perfmon_binding *b, cycles_t time)
24{
25    errval_t err;
26    err = boot_perfmon_pong__tx(b, NOP_CONT, time);
27    if (err_is_fail(err)) {
28        USER_PANIC_ERR(err, "sending ping failed");
29    }
30}
31
32void pong(struct boot_perfmon_binding *b, cycles_t time)
33{
34    errval_t err;
35
36    timestamp[id].time[counter] = bench_tsc() - time - bench_tscoverhead();
37    counter++;
38
39    if (counter != MAX_COUNT) { /* Continue with same core */
40        err = boot_perfmon_ping__tx(b, NOP_CONT, bench_tsc());
41        if (err_is_fail(err)) {
42            USER_PANIC_ERR(err, "sending ping failed");
43        }
44
45    } else { /* Run tests with another coreid */
46
47        err = coreset_get_next(set, &token, &id);
48        if (err_is_fail(err)) {
49            if (err_no(err) == LIB_ERR_CORESET_GET_NEXT_DONE) {
50                /* Done running tests with all cores */
51                retcb();
52                return;
53            } else {
54                USER_PANIC_ERR(err, "coreset_get_next failed");
55            }
56        }
57
58        struct boot_perfmon_binding *nb;
59        err = relations_get(rel, id, &nb);
60        if (err_is_fail(err)) {
61            USER_PANIC_ERR(err, "relations_iterate failed");
62        }
63
64        counter = 0;
65        err = boot_perfmon_ping__tx(nb, NOP_CONT, bench_tsc());
66        if (err_is_fail(err)) {
67            USER_PANIC_ERR(err, "sending ping failed");
68        }
69    }
70}
71
72/**
73 * \brief Run tests
74 *
75 * Only called on the leader
76 */
77errval_t tests(callback cb)
78{
79    errval_t err;
80    retcb = cb;
81
82    /* Allocate space to store data */
83    timestamp = malloc(sizeof(struct timestamp) * coreset_count(set));
84    if (!timestamp) {
85        return LIB_ERR_MALLOC_FAIL;
86    }
87
88    /* Get the next core id to run the test with */
89    token = CORESET_INIT_TOKEN;
90    err = coreset_get_next(set, &token, &id);
91    if (err_is_fail(err)) {
92        USER_PANIC_ERR(err, "coreset_get_next failed");
93    }
94
95    // Make sure it isn't my_core_id
96    if (id == my_core_id) {
97        err = coreset_get_next(set, &token, &id);
98        if (err_is_fail(err)) {
99            USER_PANIC_ERR(err, "coreset_get_next failed");
100        }
101    }
102
103    // Look up the binding
104    struct boot_perfmon_binding *b;
105    err = relations_get(rel, id, &b);
106    if (err_is_fail(err)) {
107        USER_PANIC_ERR(err, "relations_iterate failed");
108    }
109
110    // Start the test
111    counter = 0;
112    err = boot_perfmon_ping__tx(b, NOP_CONT, bench_tsc());
113    if (err_is_fail(err)) {
114        USER_PANIC_ERR(err, "sending ping failed");
115    }
116
117    return SYS_ERR_OK;
118}
119