1/** \file
2 *  \brief Memory server benchmark application, testing memory stealing.
3 *
4 *  Run it with and without memory stealing turned on in the mem_serv.
5 */
6
7/*
8 * Copyright (c) 2010-2011, ETH Zurich.
9 * All rights reserved.
10 *
11 * This file is distributed under the terms in the attached LICENSE file.
12 * If you do not find this file, copies can be found by writing to:
13 * ETH Zurich D-INFK, Universitaetstrasse 6, CH-8092 Zurich. Attn: Systems Group.
14 */
15
16/*
17 * Spawn benchmark on given # of cores.
18 * Request set amount of memory on each core.
19 * This benchmark program waits on barriers to ensure that the mem server is
20 * running and to synchronise the starting and stopping of the benchmarks on
21 * different dispatchers.
22 */
23
24#include <stdio.h>
25#include <stdlib.h>
26
27#include <barrelfish/barrelfish.h>
28#include <barrelfish/spawn_client.h>
29
30#include <trace/trace.h>
31#include <trace_definitions/trace_defs.h>
32
33#include "memtest_trace.h"
34
35#include "sleep.h"
36
37#define MAX_REQUESTS 10
38#define MAX_REQUESTS_0 10
39#define MEM_BITS 20
40
41#define MINSIZEBITS 9 // from mem_serv.c
42
43static void run_benchmark(coreid_t core, int requests)
44{
45    errval_t err;
46    struct capref ramcap;
47
48    // the actual test runs on one core, so that it can steal from other
49    // cores
50    if (core != 1) {
51        debug_printf("core %d NOT participating in test\n", core);
52        return;
53    }
54
55    int i = -1;
56    int bits = MEM_BITS;
57
58    debug_printf("starting benchmark. allocating mem of size: %d\n", bits);
59
60    sleep_init();
61
62    do {
63        i++;
64        // bits =  MINSIZEBITS+i;
65        trace_event(TRACE_SUBSYS_MEMTEST, TRACE_EVENT_MEMTEST_ALLOC, i);
66        err = ram_alloc(&ramcap, bits);
67        // milli_sleep(1);
68
69        if ((i % 500 == 0) && (i > 0)) {
70            debug_printf("allocated %d caps\n", i);
71        }
72
73    } while (err_is_ok(err)); // && (i < requests));
74
75    debug_printf("done benchmark. allocated %d caps (%lu bytes)\n",
76                 i, i * (1UL << bits));
77
78}
79
80
81
82static int run_worker(coreid_t mycore)
83{
84    errval_t err;
85
86    trace_event(TRACE_SUBSYS_MEMTEST, TRACE_EVENT_MEMTEST_WAIT, 0);
87
88    err = nsb_worker((int)mycore, "mem_bench_ready");
89    if (err_is_fail(err)) {
90        USER_PANIC_ERR(err, "barrier_worker failed");
91    }
92
93    trace_event(TRACE_SUBSYS_MEMTEST, TRACE_EVENT_MEMTEST_RUN, 0);
94
95    run_benchmark(mycore, MAX_REQUESTS);
96
97    trace_event(TRACE_SUBSYS_MEMTEST, TRACE_EVENT_MEMTEST_WAIT, 0);
98
99    err = nsb_worker((int)mycore, "mem_bench_finished");
100    if (err_is_fail(err)) {
101        USER_PANIC_ERR(err, "barrier_worker failed");
102    }
103
104    trace_event(TRACE_SUBSYS_MEMTEST, TRACE_EVENT_MEMTEST_DONE, 0);
105
106    return EXIT_SUCCESS;
107}
108
109static int run_master(coreid_t mycore, int argc, char *argv[])
110{
111    //    assert(mycore == 0);
112
113    errval_t err;
114    int num_spawn = strtol(argv[1], NULL, 10);
115    int first_core = mycore + 1;
116
117    debug_printf("spawning on %d cores\n", num_spawn);
118
119#ifdef TRACING
120    err = init_tracing();
121    if (err_is_fail(err)) {
122        DEBUG_ERR(err, "initialising tracing");
123        return EXIT_FAILURE;
124    }
125    // start_tracing();
126
127    prepare_dump();
128#endif
129
130    trace_event(TRACE_SUBSYS_MEMTEST, TRACE_EVENT_MEMTEST_STARTED, 0);
131
132    // spawn some dispatchers
133
134    char *path = argv[0];      // reuse argv and path
135    argv[1] = NULL;
136
137    for (int i = first_core; i <= num_spawn; i++) {
138        err = spawn_program(i, path, argv, NULL, 0, NULL);
139        if (err_is_fail(err)) {
140            DEBUG_ERR(err, "spawning on core %d", i);
141        } else {
142            //debug_printf("dispatcher %d on core %d spawned\n", i, i);
143        }
144
145    }
146
147    trace_event(TRACE_SUBSYS_MEMTEST, TRACE_EVENT_MEMTEST_WAIT, 0);
148
149    //    debug_printf("waiting for all spawns to start\n");
150    err = nsb_master(first_core, num_spawn, "mem_bench_ready");
151    if (err_is_fail(err)) {
152        DEBUG_ERR(err, "failed barrier_master");
153        return EXIT_FAILURE;
154    }
155
156    start_tracing();
157
158    trace_event(TRACE_SUBSYS_MEMTEST, TRACE_EVENT_MEMTEST_RUN, 0);
159
160    //    run_benchmark(mycore, MAX_REQUESTS_0);
161
162    trace_event(TRACE_SUBSYS_MEMTEST, TRACE_EVENT_MEMTEST_WAIT, 0);
163
164    //    debug_printf("waiting for all spawns to complete\n");
165    err = nsb_master(first_core, num_spawn, "mem_bench_finished");
166    if (err_is_fail(err)) {
167        DEBUG_ERR(err, "failed barrier_master");
168        return EXIT_FAILURE;
169    }
170
171    trace_event(TRACE_SUBSYS_MEMTEST, TRACE_EVENT_MEMTEST_DONE, 0);
172
173    debug_printf("all benchmarks completed\n");
174
175#ifdef TRACING
176    stop_tracing();
177    // dump_trace();
178#endif
179
180    return EXIT_SUCCESS;
181}
182
183
184int main(int argc, char *argv[])
185{
186    coreid_t mycore = disp_get_core_id();
187
188    debug_printf("This is mem_bench_6\n");
189
190    if (argc < 2) {
191        return run_worker(mycore);
192    } else {
193        return run_master(mycore, argc, argv);
194    }
195}
196