1/**
2 * \file
3 * \brief Phase-change performance benchmark
4 */
5
6/*
7 * Copyright (c) 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 <barrelfish/waitset.h>
18#include <barrelfish/resource_ctrl.h>
19#include <barrelfish/sys_debug.h>
20#include <bench/bench.h>
21
22#define ITERATIONS      1000
23#define DELAY           100     /// Cooldown delay between iterations in ms
24
25static const char *my_manifest =
26    "B 1\n"                     // Normal phase
27    "B 1\n";                    // Other normal phase
28
29static int init_done = 1;
30static rsrcid_t my_rsrc_id;
31static struct thread_sem init_sem = THREAD_SEM_INITIALIZER;
32
33static int remote_init(void *arg)
34{
35    errval_t err = rsrc_join(my_rsrc_id);
36    assert(err_is_ok(err));
37    thread_sem_post(&init_sem);
38    return 0;
39}
40
41static void domain_spanned(void *arg, errval_t reterr)
42{
43    assert(err_is_ok(reterr));
44    init_done++;
45}
46
47int main(int argc, char *argv[])
48{
49    int my_core_id = disp_get_core_id();
50    errval_t err;
51    static cycles_t timestamp[ITERATIONS];
52    uint64_t tscperms;
53
54    if(argc < 2) {
55        printf("Usage: %s threads\n", argv[0]);
56    }
57    int nthreads = atoi(argv[1]);
58
59    err = sys_debug_get_tsc_per_ms(&tscperms);
60    assert(err_is_ok(err));
61
62    bench_init();
63
64    // Submit manifest (derived from program)
65    err = rsrc_manifest(my_manifest, &my_rsrc_id);
66
67    /* Span domain to all cores */
68    for (int i = my_core_id + 1; i < nthreads + my_core_id; i++) {
69        err = domain_new_dispatcher(i, domain_spanned, NULL);
70        if (err_is_fail(err)) {
71            DEBUG_ERR(err, "failed to span domain");
72        }
73        assert(err_is_ok(err));
74    }
75
76    while(init_done < nthreads) {
77        thread_yield();
78    }
79
80    for (int i = my_core_id + 1; i < nthreads + my_core_id; i++) {
81        err = domain_thread_create_on(i, remote_init, NULL, NULL);
82        assert(err_is_ok(err));
83        thread_sem_wait(&init_sem);
84    }
85
86    // Run benchmark
87    bool flip = false;
88    for(int i = 0; i < ITERATIONS; i++) {
89        flip = !flip;
90        cycles_t start = bench_tsc();
91        err = rsrc_phase(my_rsrc_id, flip ? 1 : 0);
92        assert(err_is_ok(err));
93        cycles_t end = bench_tsc();
94        timestamp[i] = end - start;
95
96        // Let it cool down
97        while(bench_tsc() < end + (DELAY * tscperms));
98    }
99
100    for(int i = 0; i < ITERATIONS; i++) {
101        printf("duration %d: %" PRIuCYCLES "\n", i, timestamp[i]);
102    }
103
104    printf("number of threads: %d\n", nthreads);
105    printf("client done.\n");
106    return 0;
107}
108