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